[Pcsclite-muscle] Directly using RSA key of a smartcard

David Woodhouse dwmw2 at infradead.org
Sat Jun 24 03:54:41 PDT 2023


On Fri, 2023-06-23 at 19:30 -0400, Michael Conrad wrote:
> It sounds like the biggest obstacle to using a user-provided yubikey is 
> that there are a lot of configuration variables that could make it 
> unusable for the script, unless maybe I ask them for their pin and store 
> that alongside the encrypted file.  Maybe we'll need to provide a 
> pre-configured yubikey.  (or maybe I can find something cheaper that 
> meets the requirements)

Hm, what configuration variables are there?

If a user wants to provide a Yubikey, they just need to tell you the
public key of the key they stored on it (so you can encrypt the ZFS key
to it), and the serial# of their Yubikey (so you know what filename to
store the encrypted key with).

If you *want* to use a PIN and require human interaction to decrypt,
you can do that. But I'm not sure it adds much value. Just use slot 9E
as in my example, and decryption works without a PIN.

So a user sends you 'public-108421384210c3f5.pem' with the output from
when they ran 'yubico-piv-tool -s9e -ARSA2048 -agenerate' on their
Yubikey with that serial#. You encrypt your raw ZFS key with it and
store it on some directory in the server:

cat raw-zfs-decryption-key |
openssl pkeyutl -encrypt -pubin -inkey public-108421384210c3f5.pem > /etc/zfs-decryption-keys/zfskey-108421384210c3f5.bin


Now all you need is a script triggered by udev (or running from cron if
that's simpler) which does something like (utterly untested; typed
straight into email)...

====================
#!/bin/sh

if zfs_is_already_unlocked; then
    exit 0
fi

# If running from cron rather than from udev and *triggered* by
# the Yubikey USB device being plugged in then...
if ! lsusb | grep -q Yubico.com; then
    # No Yubikey present
    exit 0
fi


YUBISERIAL=$(p11tool --list-tokens | sed -n '/URL:.*manufacturer=piv_II;/s/.*serial=\(.*\);.*/\1/p')
if [ -z "$YUBISERIAL" ]; then
    # No PIV found
    exit 0
fi

ZFSKEY="/etc/zfs-decryption-keys/zfskey-${YUBISERIAL}.bin"
if [ ! -r "${ZFSKEY}" ]; then
    # No decryption key for this Yubikey
    exit 0
fi

openssl pkeyutl -decrypt -in "${ZFSKEY}" -engine pkcs11 -keyform engine  -inkey "pkcs11:manufacturer=piv_II;serial=${YUBISERIAL};id=%04" | unlock_zfs_using_key_on_stdin

====================

Then they just plug their Yubikey in, wait for the script to run, and
the file system is unlocked.

If your ZFS key is larger than the Yubikey's RSA key, you may want to
use 'openssl cms' for encryption/decryption instead of the raw pkeyutl.
In that case, they need to generate a self-signed certificate for the
key in their Yubikey, and send you that instead of the raw public key.

Then your encryption step when they send you their cert becomes:

cat raw-zfs-decryption-key |
openssl cms -encrypt -recip cert-108421384210c3f5.pem > /etc/zfs-decryption-keys/zfskey-108421384210c3f5.bin

And the decryption in the last line of the script becomes:

openssl cms -decrypt -in ${ZFSKEY} -keyform engine -engine pkcs11 -inkey "pkcs11:manufacturer=piv_II;serial=${YUBISERIAL}id=%04" | unlock_zfs_using_key_on_stdin


-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5965 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/pcsclite-muscle/attachments/20230624/591ce531/attachment-0001.p7s>


More information about the pcsclite-muscle mailing list