In this post I’ll use a Yubikey, running the PIV application, to store a keypair and certificate to be used for mutual TLS. The Yubikey will generate the private key on the device, and the private key will never leave the device. Nice for security!

I’ll also configure Firefox to discover the certificate stored on the device, so it can be used when browsing to a site requiring a client certificate.

Let’s start by installing yubico-piv-tool since it contains the plugin required for Firefox, as well as tools required to communicate with the Yubikey.

yay -S yubico-piv-tool

Prepare Yubikey PIV

First we need to configure the Yubikey PIV application, which is the application that stores the certificate. Instructions are based on [1].

First we need to set the management key, save it in a password manager or similar, you need it for device changes in the future. Here we generate a random key, print it, and then set it.

key=$(export LC_CTYPE=C; dd if=/dev/urandom 2>/dev/null | tr -d '[:lower:]' | tr -cd '[:xdigit:]' | fold -w48 | head -1)
echo ${key}
yubico-piv-tool -aset-mgm-key -n${key}

Then wechange the PIN and PUK code. In my case, I set the PIN to something I remember by heart. The PUK code is just set to some random numbers, which I then forget. If I forget my PIN, I’ll just reset the device and recreate all keys instead. The default PIN and PUK is 123456 and 12345678 respectively. The PIN is the code you will use when visiting sites requiring you to present the certificate.

puk=$(export LC_CTYPE=C; dd if=/dev/urandom 2>/dev/null | tr -cd '[:digit:]' | fold -w8 | head -1)
echo ${puk}

yubico-piv-tool -achange-pin
yubico-piv-tool -achange-puk -P12345678 -N${puk}

Finally, to be able to actually use the key, you need to generate a CHUID and CCC.

yubico-piv-tool -k"${key}" -aset-chuid -aset-ccc

Generate private key and CSR

First, generate the private key on the Yubikey, exporting only the public key.

yubico-piv-tool -k"${key}" -a generate -s 9a -A RSA2048 -o yubikey_piv.pub

Then generate a CSR, use the following command. You need to replace the DN (Distinguished Name) with the correct string for your purposes.

yubico-piv-tool -s 9a -S "/C=SE/L=Lund/O=ORG_NAME/CN=Linus Karlsson @ Yubikey/" -a verify -a request -i yubikey_piv.pub -o yubikey_piv.csr

You now need to send the CSR for signing by a certificate authority (CA). When signed, you’ll get a certificate back, which we’ll assume is stored in yubikey_piv.crt. Import it to the Yubikey by using.

yubico-piv-tool -k"${key}" -a import-certificate -s 9a -i yubikey_piv.crt

The Yubikey is now ready!

Configure Firefox to use client certificate

Go to Firefox settings -> Privacy & Security. Scroll down and click Security devices. Finally click the button “Load”. In the dialog, enter the following values:

Module name: Yubikey PIV
Module filename: /usr/lib/libykcs11.so

After clicking OK, you should be able to see the Yubikey in the list of devices.

After this you should be able to visit a site requiring client certificates. You will first need to enter the PINin the dialog that appears, as well accept the certificate.

References

[1] https://developers.yubico.com/yubico-piv-tool/YubiKey_PIV_introduction.html