[continued from part I]
Life-cycle of an authentication token can be divided into roughly three stages:
- Initial setup. This includes steps such as acquiring the hardware, generating keys and provisioning credentials on the token and setting an initial PIN before handing it over to the user.
- Normal usage, namely SSH authentication with private keys on the token. This also includes changing the PIN as necessary.
- “Administrative” maintenance such as resetting a forgotten PIN, clearing out all credentials on the token for transfer to another user or issuing new keys.
This post will focus on the second part, namely using the token for SSH authentication on OS X. But it is worth pointing out that the lines between provisioning and steady-state usage are somewhat arbitrary. For example users could receive completely uninitialized tokens and handle key generation on their own, just as SSH keys are typically generated unassisted on end-user machines. Since SSH only cares about the raw cryptographic key, it does not matter whether users load a self-signed certificate or one obtained from their own CA. It would be a different story if the use-case called for certificates chaining up to a trusted authority. That said, there is some benefit to performing the key-generation in a trusted environment and noting the public-key directly. For example it can be used to enforce a policy that employees can only use SSH keys that were generated in hardware. (PIV standard does not provide a way to generate such an attestation after the fact to prove that a particular public-key was generated in hardware.)
OS X setup
These instructions assume that the token has been personalized with default PIN and secret question/answer and PIV authentication certificate was provisioned. Subsequent posts will take up some of the subtleties around performing key-generation on the token as well as wiping out and reinitializing tokens that have credentials present.
1. Check openssh version and upgrade if necessary
While openssh uses PKCS #11 interface, it is dependent on a compile time macro which can be configured to include or exclude that functionality. Earlier versions may have been more inclined to opt-out, possibly because PKCS support was not stable. Of course Apple is notorious for shipping ancient versions of open-source software, so it comes as no surprise that the version of openssh built into OS X 10.8 does not have smart-card support.
OS X 10.9 ships with a more recent vintage 6.2 from March 2013 which has been compiled with PKCS support. (That said, this version as built by Apple still has a serious bug that breaks agent-forwarding and PIN caching that we will describe later.)
For reference the latest stable release as of this writing is 6.6p1 from March 2014.
2. Install required software
Also install the GoldKey client for OS X which is required for changing the PIN. Note that the GoldKey PIV application does not honor the CHANGE AUTHENTICATION DATA command that is normally used on PIV cards to set a new PIN. Instead the entire token including any optional encrypted flash-drive has a single unified PIN controlled via the GoldKey management interface which also prompts for secret question. That process takes place via GoldKey utility, (not to be confused with “GoldKey Vault” also installed by the same package) selecting “GoldKey information” from the menu and clicking on “Personalize.”
3. Modify SSH configuration
In principle this step is optional, since the PKCS module can be specified in the ssh command line using the -I option during invocation. But doing that every time is inconvenient and some utilities such as git expect to invoke “ssh” with no additional parameters by default, leaving out the hardware token support.
Specify the path to the PKCS #11 module such as:
There is one pitfall here as cautioned in the documentation for openssh: if the configuration includes an Identities or IdentityFile directive, it can interfere with the ability to leverage additional credentials present on the token.
4. Export SSH public-key from token
ssh-keygen has support for downloading an existing public key from the token:
ssh-keygen -I /usr/lib/opensc_pkcs11.so
(Somewhat confusingly, this does not in fact perform key-generation on the token; it only retrieves existing credentials already present.)
A more round-about way of accomplishing the same task is to read out the PIV authentication certificate and format the public-key in the certificate in a suitable format required by openssh. For example OpenSC project includes a pkcs11-tool for retrieving arbitrary data-objects from the card application by label, including certificates. openssl can be used to extract the public-key field out of that certificate and passed to ssh-keygen to convert from PKCS #8 into the native ssh format.
pkcs11-tool --module /usr/lib/opensc-pkcs11.so\ -r -a "Certificate for PIV Authentication" --type cert |\ openssl x509 -inform DER -pubkey -noout |\ ssh-keygen -i -m PKCS8 -f /dev/stdin
Verifying the setup
At this point the configuration can be verified against any ssh server. Here is an example involving Github, which supports multiple SSH keys associated with an account– very convenient for testing before switching 100% to hardware tokens:
$ git pull Enter PIN for 'PIV_II (PIV Card Holder pin)': remote: Counting objects: 1234, done. ...
Second line highlighted above is the prompt for a PIN associated with the PKCS #11 module.
The next post will discuss some edge-cases around using the token with other applications, as well as pitfalls around SSH agent-forwarding, which does not function correctly with the version of openssh utilities shipped in OS X 10.9.