-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Accept pkcs11: URIs for EAP certificates and private keys #3942
base: master
Are you sure you want to change the base?
Conversation
On systems where the libp11 "pkcs11" OpenSSL ENGINE plugin[0] is installed, allow the user to request keys and certs from an HSM or smartcard instead of storing them in the clear on disk. [0] https://github.com/OpenSC/libp11
This definitely seems interesting. It's a tiny patch, which helps rather a lot in getting it merged. |
Yeah it's interesting, but from a usability perspective interacting with the PKCS11 engine by overloading the certificate configuration items isn't great. Is there any definition of the PKCS11 configuration items? Could we add a better defined interface? |
The main issue with using different configuration items is that much code assumes that certificate_file, etc. are not empty. We'd have to double-check that. If we were to follow the more abstract representation, we might change the configuration options to more URL-style references?
but that's a little fugly. As nothing else in the configuration uses Just checking the rest of the configuration, pretty much only the TLS configuration uses So I'd be happy to remove the
that seems a little clearer |
Probably wants more granularity from that. If you look at the patch it only adds the ability to load the server cert and the private key using the PKCS engine, intermediary CAs still come from files.
Server certs/validation options and client certs/validation options probably want to go in |
Yeah... it's probably useful to support multiple formats. I'll have to check if OpenSSL will automatically read the different formats. The configuration already supports |
PKCS11 URI scheme https://tools.ietf.org/html/rfc7512 |
I modeled this on the client side (wpa_supplicant) configuration, where you can just replace the filenames with PKCS#11 URIs: https://superuser.com/questions/1510368/configuring-wpa-supplicant-to-use-tpm2-pkcs11-tools
The OpenSSL CLI programs want you to specify |
wpa_supplicant has:
so we could do something similar here. Putting all of the text into a large blob just seems bad: |
yeah there's no way I would push creating that URI correctly onto the user. Getting them to correctly escape the different values, and correctly infer the underlying data type is just a non-starter. I mean |
Except for the For specifying the PIN, maybe overload Edit: Here is a useful guide on finding PKCS#11 URIs. Also note that the ID field might not be as simple as |
Some other examples, from playing with SoftHSM:
ID can be an arbitrary hex string, not just a single byte.
If we really want maximum flexibility, we could let the user pick a different OpenSSL ENGINE from I still think there is value, however, in maintaining a special case that lets a user just paste a standard pkcs11: URI into the private_key field with no further configuration, since that is such a common use case that works with a wide variety of cryptographic hardware. |
@nickrbogdanov that's definitely a more compelling argument to accept pkcs11 URIs.
The config pairs you're overloading should have had the We can add logic to the I'll take a proper look at implementing this tomorrow, it shouldn't be difficult. |
The overloading was inspired by this functionality from wpa_supplicant:
They also have similar logic that autodetects TPM2 keys and sets the If we drop the overloading, I would suggest adding generic ENGINE support in lieu of a special case for pkcs11. For a file:
For ENGINE:
If
|
Still working on this. I added a lot of the infrastructure needed for dynamically loaded engines in |
Definite +1 for supporting this functionality. An observation about OpenSSL v3 and up - the engine interface has been deprecated in favour of the provider interface: https://wiki.openssl.org/index.php/OpenSSL_3.0 For this reason it would be best to avoid the word "engine" in the configuration syntax. The URL syntax is immune to the goings on underneath, and is defined in an RFC. |
06700bb
to
8dc35c2
Compare
Conversations at the IETF have demonstrated why this URL scheme is useful. If someone wants to rework this for OpenSSL 3.x we'd accept the patches. |
76ed4dd
to
48ca41e
Compare
78c97fd
to
1a249f5
Compare
We're revisiting this functionality as we're looking at using TPMs internally for our own security. |
@nickrbogdanov: Have you progressed on your PR? |
We're looking at using TPMs internally within Inkbridge now (the commercial side of the project), so we'll need this functionality or equivalent. Expect to see something in master branch before Q1 2025. |
On systems where the libp11 "pkcs11" OpenSSL ENGINE plugin is installed, allow the user to request keys and certs from an HSM or smartcard instead of storing them in the clear on disk.
This is useful because revoking a leaked EAP server certificate can be highly disruptive, especially if there are many deployed devices and IoT gadgets that connect to the network exclusively via 802.1x. Storing the private key on a smartcard ensures that it cannot be extracted if the RADIUS server is compromised.
Performance-wise, I see penalties ranging from ~90ms per TLS handshake (ECC256) to 160ms (RSA2048) on a YubiKey 4. I would expect that higher-grade HSM hardware would be much faster, but I don't have access to it for testing.
To test this on Ubuntu 20.04 with a YubiKey, I set up a local installation with an on-disk private key, tested it with
radiusd -X
, and then moved it to the smartcard:(I had to use
yubico-piv-tool
instead of the standardpkcs11-tool
becauseC_CreateObject
is apparently unsupported.)Then I edited the
mods-enabled/eap
file to add a PKCS#11 URI with thepin-value
property set:I then restarted
radiusd -X
and used a test client /eapol_test
to verify that the server still worked correctly.I don't really expect most users to set things up so that interactive PIN entry is required, but I did test that case. When running
radiusd -X
from the command line, OpenSSL will prompt for a PIN; without-X
the daemon will log an appropriate error and exit.The one thing I wasn't able to figure out is how to import the entire certificate chain into the YubiKey's X.509 certificate slot (if such a thing is even possible). So I suspect that loading
certificate_file
from PKCS#11 is mainly useful if the server certificate is self-signed.Also, I didn't test this against old versions of OpenSSL, and I didn't test the case where OpenSSL is missing ENGINE support (which I suspect will already break the existing
fr_openssl_init()
code).