Hacker News new | ask | show | jobs
by cronos 1896 days ago
PKCS#11 is a C API. It does not describe the wire format for talking to the actual hardware.

To use PKCS#11 for a particular device, you need a module (shared library) to translate between the C API and the actual hardware. This module is usually vendor-specific.

If I develop software with PKCS#11 support, I'm basically asking every user to find a PKCS#11 module from their device vendor and install it in the right place.

With U2F at least the hardware wire format is standardized: https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fid...

2 comments

The wire format is standardized: ISO 7816. Even U2F uses ISO 7816.

This issue with existing smart card technology is not lack of standardization, it's too much standardization--too much flexibility and stacks that are too deep.

Vendors ship their own PKCS#11 drivers as a convenience. But PKCS#11 isn't the only high-level API. The other is PC/SC, which is actually simpler than PKCS#11, though it often requires more local support from the OS. But not necessarily. You can write PC/SC shims that talk directly to hardware, or even to Vault servers if you want, w/o OS support. I have my own rapid driver framework that supports all of these. For example, I have a PKCS#11 and PC/SC client driver which can use the Apple T1 chip to authenticate to a Vault server for remote signing using Transit keys--the only engine that supports ad hoc remote key operations. This permits sharing GnuPG (via PC/SC) and OpenSSH (via PKCS#11) keys between users, without actually disclosing the keys, though Vault actually makes it difficult to do this securely as you need to write ACLs to prevent transit keys from being exportable.

BTW, you don't need special drivers to use Yubikeys, either. They just provide them as a convenience because the FOSS ecosystem is confusing and... non-optimal.

I'm hoping to release a macOS product soon and as part that may release some of my framework as FOSS.

That level of standardization is a feature, not a bug. PKCS#11 lets you use any compliant hardware device with any compliant software package, as long as they both implement the spec. Compliant software packages include: ssh, Java's keytool, the GnuTLS utilities, the openssl utilities, wpa_supplicant, various web browsers, and VPN clients. Nowadays many popular Linux distributions come with p11kit configured out of the box, which lets openssl/GnuTLS autoselect the correct PKCS#11 shared library based on the matching information in the PKCS#11 URI.

While the low level API is complex and the UI often isn't ideal, PKCS#11 has been a godsend for interoperability because it abstracts out the low level hardware interfaces and other implementation details. It lets your application seamlessly access hardware-backed keys whether the keystore is sitting on USB (Yubikey), ISO7816 (smartcard), I2C (TPM), or something else. On the application side, adding PKCS#11 support only takes about a dozen lines of code, after which the app can use hardware backed keys/certs to perform TLS negotiations.