GNOME Bugzilla – Bug 719982
Add support to use the PKCS #11 OpenSSL engine for 802.1x EAP-TLS [Patch included]
Last modified: 2017-02-25 21:23:16 UTC
Hi everyone, WPA supplicant supports to use the PKCS #11 OpenSSL engine for 802.1x EAP-TLS. Network Manager so far does not support to hand down the required configuration options to WPA supplicant. The proposed patch adds the missing configuration options for EAP-TLS phase 1 and the needed code to hand them down to WPA supplicant as part of the network and interface configuration. The new configuration options are: engine key-id cert-id ca-cert-id pkcs11-engine-path pkcs11-module-path All of the new configuration options are optional as it depends on the actual PCKS #11 module in use which options are needed - if any. Unfortunately the PKCS #11 standard gives no way to check what is actually needed and so Network Manager can't check much of these new configuration options. :-/ The new code introduced by the patch is completely inactive as long as the engine option is not set to 1 to enable the PKCS #11 OpenSSL engine support. Once the engine support is enabled the following changes apply: * 'engine_id' in the network configuration will be set to 'pkcs11'. * 'key_id' in the network config will be set with the 'key-id' value if it is set. Furthermore if 'private-key' is set, then Network Manager will give an error as the private key is handled via the PKCS #11 OpenSSL engine. * 'cert_id' in the network config will be set with the 'cert-id' value if it is set. Alternatively - depending on the PKCS #11 module in use - 'client-cert' can be used to specify the client certificate. Both 'cert-id' and 'client-cert' are optional in this case, as the PKCS #11 module in use might not require this option to determine the client certificate. * 'ca_cert_id' in the network config will be set with the 'ca-cert-id' value if it is set. Alternatively - depending on the PKCS #11 module in use - 'ca-cert' can be used to specify the CA certificate. Both 'ca-cert-id' and 'ca-cert' are optional in this case, as the PKCS #11 module in use might not require this option to determine the CA certificate. * If 'pkcs11-engine-path' and 'pkcs11-module-path' are specified (both need to be absent or set) then the 'pkcs11_engine_path' and the 'pkcs11_module_path' will be set via the 'SetPKCS11EngineAndModulePath' D-Bus method . For more details and patches for current WPA supplicant versions see http://w1.fi/bugz/show_bug.cgi?id=499. These two options are also optional as these paths can alternatively be set via the OpenSSL configuration. If you have a look on the attached test instructions then I'm sure these confusing options will make more sense. ;-) Please let me know what you think about the patch. Best, Michael Schaller <misch@google.com> (Author) Sebastian Harl <tokkee@google.com; tokkee@debian.org> (Reviewer)
Created attachment 263678 [details] Instructions how to manually test this patch
Created attachment 263679 [details] [review] Patch to add support to use the PKCS #11 OpenSSL engine for 802.1x EAP-TLS
I know it's a bit too early to ask, but is there any chance we could look at this - and maybe finish it - before Christmas 2013?
Created attachment 266987 [details] [review] Fixup white spaces This patch applies directly on yours, and fixes up some white space according our style. Just to be pedantic :) I did not test it, but it looks good to me. ACK
Thomas, thanks for picking this one up. To test this change see the attached instructions. Furthermore please have a look especially at the PIN handling. I'm not sure if there is some better way to make the PIN an optional secret. To make the PIN an optional secret I've changed: 1) The default value from NM_SETTING_SECRET_FLAG_NONE to NM_SETTING_SECRET_FLAG_NOT_REQUIRED in nm_setting_802_1x_get_pin_flags. 2) The PROP_PIN setter in set_property to remove the NM_SETTING_SECRET_FLAG_NOT_REQUIRED bit if a PIN has been set. Please note that I did not change the EAP-SIM implementation and so the PIN will still be mandatory for EAP-SIM.
Patches for adding pkcs#11 stuff have been floating around for years: https://bugzilla.gnome.org/show_bug.cgi?id=537237 https://bugzilla.gnome.org/show_bug.cgi?id=537239 and while they are pretty close, I'd rather not add any of the PKCS#11 module path or engine stuff to NetworkManager at all. Instead, that should be handled by something like p11kit (or even opencryptoki), where the pkcs11 module is always the helper library's module (eg, p11kits). Typically the helper library then handles all the certificate IDs. So, ideally, we would not need any changes to the NM settings, because we already have the mechanism: schemes. So, I would add another enum to NM_SETTING_802_1X_CK_SCHEME_* called NM_SETTING_802_1X_CK_SCHEME_ID and update the logic to add an "id://" like we have "file://". We could also add new helpers like: nm_setting_802_1x_get_client_cert_id() since we have them for blobs and files too. The "ID" scheme would be the certificate/key fingerprint as given to the applet by p11kit/opencryptoki/whatever. NetworkManager then sets up wpa_supplicant with the configured openssl engine without the user having to specify what the engine is, since NM knows which one it is already. It passes the fingerprints to the supplicant, and the supplicant handles all further interaction. The connection editor would then be changed to use a certificate chooser widget instead of a file picker, and the chooser widget would somehow allow the user to import certificates into the certificate store, and the editor would then exclusively use the fingerprint, not the path. At least, that's what I was thinking the endgame would be for better certificate support.
Hi Dan, I know that there are patches floating around. In fact David Smith - who opened these bugs - is a former team colleague of mine. I had an in-depth look on the previous patches and I wasn't particularly happy with them as they were in my opinion too broad. I would like to get some basic, well understood and to the point PKCS #11 support into Network Manager to get started and then iterate from there. That is what the new patch is about. I personally don't know the full background what happened and has been discussed back then. Reading the old bugs and your reply from yesterday sounds very much like you have a greater vision in mind how to improve the general situation so that it also covers the PKCS #11 case. If this can be done with p11-kit then I'm excited about it and I'm highly interested to finally work this out! Dan, if I understand your proposal correctly then you would like to alter NM so that it can lookup certificates similar to how Firefox and Chrome can lookup certificates (https://wiki.gnome.org/Projects/CryptoGlue/Integration). Correct? How much work and time do you think this effort would require? What changes to WPA supplicant would be needed? What changes to NM would be needed? Dan, I'm asking this because I would like to know if it could make sense to get at least the rudimentary PKCS #11 support submitted for the time being. The lacking PKCS #11 support is a long standing issue for us and most likely others. It is also kinda expensive to maintain this out of tree PKCS #11 patch and burns quite some cycles that can be spent better - like for an instance to work on p11-kit support. ;-) Please let me know how you want to progress further. Best, Michael Schaller
Friendly ping for Dan. Dan, how should we progress further?
Another friendly ping for Dan.
And another friendly ping... It would be really nice if someone could comment how we should progress further.
Hi. Thanks for your patch. I have one question regarding the PIN. I wasn't able to use my token without writing the PIN in cleartext in the network manager configuration file. Am I missing something or is it the expected behavior for the moment ? Regards, Grégoire Menuel
(In reply to comment #11) Hi Grégoire Menuel, Sorry for the late answer. Does Network Manager ask you for the pin if you remove your pin from the configuration and add the line 'pin-flags=0'? The reason for this behavior is that the pin is optional ('pin-flags=4') by default. If you specify a pin in the configuration then this will automatically imply 'pin-flags=0' to tell Network Manager that the pin is required. Please also see comment #5 in this bug. To me it looks like there is no other secret in NM that is optional. So maybe my attempt to make the pin optional isn't the best attempt or questionable in the first place. ;-) Best, Michael Schaller
Hi Michael. I tried again with pin-flags=0, I know have the popup from nm-applet asking for the private key password, but I still have some trouble because nm-applet tries to confirm that the password is correct for the key (which he can't do because it is not a normal TLS keyfile), even when I bypass this verification I have other problems related to that. I need to dig deeper into network-manager-applet code to see if I can make it work correctly with pkcs#11 PIN. Regards, Grégoire Menuel
(In reply to comment #13) I was under the impression that all certificate checks would be disabled in the NM core if PKCS #11 mode is enabled for EAP-TLS. So either this is a bug in the patch or NM Applet does some certificate checks on its own... Grégoire, were you able to figure out where your problems originate from?
Created attachment 280275 [details] [review] network-manager-applet patch adding EAP-TLS-PKCS11 support Hello, We have patched network-manager-applet 0.9.8.8 in order to add support for PKCS11 EAP-TLS WiFi authentication. This is still very experimental and the settings are not checked but this patch enables the creation of an EAP-TLS-PKCS11 connection entirely with the GUI. The dialog for asking the pin code works too. We hope this code can be improved and merged one day. Alexis
Hello, Could we please consider to merge 802.1X PKCS11 patches for nm and nm-applet ? We all agree that a more broad solution is necessary, but it may take a lot of time to develop. And right now we have working PKCS11 patches for the whole wpasupplicant+nm+nm-applet chain. PKCS11 WiFi is used by several organizations, there are at least us and Michael Schaller. If we didn't have to maintain out of tree patches, it would be a lot easier to work on a long term solution. Please note that we are willing to adapt the patches if they are unfit for integration yet. Best regards, Alexis
*** Bug 537239 has been marked as a duplicate of this bug. ***
*** Bug 537237 has been marked as a duplicate of this bug. ***
*** Bug 489091 has been marked as a duplicate of this bug. ***
*** Bug 590644 has been marked as a duplicate of this bug. ***
I've written up my understanding of an IRC converstation that I, Alexis, and Stef Walter had today here: https://wiki.gnome.org/Projects/NetworkManager/PKCS11 Alexis & Stef: if you could review that page and see if your understanding matches, that would be great! We can then discuss and resolve if we have different understandings. Alexis, if that approach sounds correct in general, I'm happy to help explain anything related to the implementation. If there are any pieces that aren't clear, I'll update the Wiki page until they are clear.
Hello, Thank you for this summary, it seems accurate and detailed enough to start working on the code. Regards, Alexis
Dan, thank you for writing the summary. There is one little mistake in the doc: Can you please replace 'opensc' with 'pkcs11' in the doc? I'll look into adapting my PKCS #11 patch to a p11-kit patch but I don't know when I'll have the time to do this. Hopefully this quarter...
(In reply to comment #23) > Dan, thank you for writing the summary. There is one little mistake in the doc: > Can you please replace 'opensc' with 'pkcs11' in the doc? Hmm, my understanding from the discussion with stefw was that p11kit's proxy would use opensc as the OpenSSL engine passed to wpa_supplicant? Stef, is that correct?
Dan, if I read the doc correctly then wpa_supplicant would be instructed by Network Manager to use PKCS#11 with the p11-kit Proxy Module. Quote from the p11-kit Proxy Module documentation: "The proxy module is then used as a normal PKCS#11 module would be." Link: http://p11-glue.freedesktop.org/doc/p11-kit/sharing.html
Dan, Michael .... you're both right. opensc enters the equation because it provides the OpenSSL specific plugin engine so OpenSSL can use PKCS#11. It's a shame that OpenSSL doesn't support PKCS#11 natively. OpenSSL is the last major crypto library in that regard.
I am dubious about the following quote from https://wiki.gnome.org/Projects/NetworkManager/PKCS11: "When an 802.1x-based connection is activated that includes PKCS#11 URIs, NetworkManager should call the wpa_supplicant SetPKCS11EngineAndModulePath() D-Bus method, and pass "opensc" as the engine, and "${libdir}/p11-kit-proxy.so" as the PKCS#11 module. " I think this risks conflating issues, and is probably what led to the above comment. I think it's easier just to require that the underlying applications *shall* accept PKCS#11 URIs which reference PKCS#11 tokens configured in p11-kit. With VPN clients like OpenConnect, that just works today. The GUI is lacking (bug 679860) but you can manually edit the config and replace a certificate filename with a PKCS#11 URI and it works. Other things like OpenVPN currently don't work right. OpenVPN doesn't use p11-kit (which could be worked around by telling it to load p11-kit-proxy), and uses a form of 'pkcs11-id' string which isn't the standard PKCS#11 URI (which can be converted). But ideally, OpenVPN should be *fixed* so that it uses p11-kit natively and *can* interpret proper PKCS#11 URIs without translation. The same goes for wpa_supplicant — it should just take PKCS#11 URIs. In the meantime with current versions you *might* need to work around its limitations, but let's be clear that this is a *localised* workaround, in the NM code which invokes such a legacy tool, to cope with its limitations.
Since wpa_supplicant uses the OpenSC ENGINE_PKCS11, this patch should go a long way towards making it behave sanely and use PKCS#11 URIs: http://sourceforge.net/p/opensc/mailman/message/33132605/
FWIW I fixed OpenVPN too with https://github.com/OpenSC/pkcs11-helper/pull/4 so now it accepts standard PKCS#11 URIs. You just need to tell it to use $libdir/p11-kit-proxy.so as the PKCS#11 module, although we should probably make that the default.
(In reply to comment #28) > Since wpa_supplicant uses the OpenSC ENGINE_PKCS11, this patch should go a long > way towards making it behave sanely and use PKCS#11 URIs: > http://sourceforge.net/p/opensc/mailman/message/33132605/ I've just done some testing with the patches that I've submitted at https://github.com/OpenSC/engine_pkcs11/pull/9 and can confirm that this now works with proper PKCS#11 URIs: pkcs11_engine_path=/home/dwmw2/engine_pkcs11.so pkcs11_module_path=/usr/lib64/p11-kit-proxy.so network={ ... engine=1 engine_id="pkcs11" cert_id="pkcs11:token=NSS%20Certificate%20DB;id=%01%7d%45%ee%34%e9%75%3d%1a%aa%fb%44%a4%03%05%fb%06%11%97%01" key_id="pkcs11:token=NSS%20Certificate%20DB;id=%01%7d%45%ee%34%e9%75%3d%1a%aa%fb%44%a4%03%05%fb%06%11%97%01" pin="foo" } It's still not ideal though; you shouldn't need to *tell* it to use p11-kit-proxy; that's the set of modules that are configured on the system by default so it should just do that automatically. It ought to be able to just *notice* that the string you give for private_key and/or client_cert starts with "pkcs11:" and do the right thing, without us having to get involved in explicit engine configuration. I'm about to build wpa_supplicant with GnuTLS instad of OpenSSL, and make sure it does precisely that.
(In reply to comment #30) > It ought to be able to just *notice* that the string you give for private_key > and/or client_cert starts with "pkcs11:" and do the right thing, without us > having to get involved in explicit engine configuration. And now it does... http://lists.shmoo.com/pipermail/hostap/2014-December/031550.html
Hello, It's good to see progress on proper PKCS11 URL implementation. However it seems to be far from being ready for end-users. There is still no PKCS11 token chooser GUI (is there?) for the applet. And I don't know if you already considered how the secrets such as pin codes will be handled. Will there be some kind of mechanism to detect that a token needs a pin code etc. ? In the mean time, in order to have working PKCS11 EAP WiFi, we have implemented Michael Schaller's PKCS11 patch for nm and have written a very minimal patch for nm-applet in order to ask for the pin code. A generic configuration (key ids empty) is written to system-connections. wpa_supplicant auto-detects the token without problems and nm-applet asks the user for the pin code. The whole setup works very well and has been used for a few months now. Since Michael Schaller's patch for nm and our patch for nm-applet are very small and isolated, it may be interesting to merge them so that we have a working PKCS11 WiFi stack until proper PKCS11 is ready. What do you think ? I will attach the minimal patch for nm-applet and a sample configuration file. Alexis
Created attachment 293515 [details] [review] very minimal patch for nm-applet that only adds support for PKCS11 pin code input
Created attachment 293516 [details] sample configuration that performs token auto-detection and asks for pin
Review of attachment 293515 [details] [review]: I don't like seeing the get_engine() thing. I've just fixed wpa_supplicant upstream so there's no mention of all this engine crap; you just provide a PKCS#11 URI as the cert or key.
Review of attachment 263679 [details] [review]: I think that almost all of this is now rendered obsolete by my patches which were committed to wpa_supplicant a few days ago. Now we only need to put a PKCS#11 URI in the private_key and client_cert fields, which works the same whether wpa_supplicant is built with OpenSSL or GnuTLS. We do need to sort out the PIN handling though, bearing in mind that the PIN is optional and may not be required.
wpa_supplicant patches here: http://w1.fi/cgit/hostap/commit/?id=5c8ab0d4 http://w1.fi/cgit/hostap/commit/?id=3d268b8d http://w1.fi/cgit/hostap/commit/?id=01b0d1d5 http://w1.fi/cgit/hostap/commit/?id=ddda6276 http://w1.fi/cgit/hostap/commit/?id=96955192 http://w1.fi/cgit/hostap/commit/?id=a642a52b This depends on the engine_pkcs11 fixes at https://github.com/dwmw2/engine_pkcs11/commits/master If wpa_supplicant is built with GnuTLS instead of OpenSSL, none of the above is needed — although we still need to work out PIN handling.
*** Bug 679860 has been marked as a duplicate of this bug. ***
Bug 679860 was the equivalent bug for 'allow us to configure VPN connections with certificates from PKCS#11'. I've marked it as a duplicate of this bug because they basically both come down to the same thing now that I've fixed wpa_supplicant. All we really need to do is have a GUI certificate chooser which results in a PKCS#11 URI. Then we provide that PKCS#11 URI in place of the filename, when specifying the certificate to wpa_supplicant, openconnect, openvpn, or whatever else. There should never be any reason for NetworkManager to mess with explicit OpenSSL ENGINE stuff or loading specific PKCS#11 tokens. With p11-kit working properly, that's all handled for us.
FWIW, Woodhouse's engine_pkcs11 fixes have been merged upstream and are part of 0.2.0+.
The wpa_supplicant fixes are included in v2.4 and later.
So... with the current releases of engine_pkcs11 and wpa_supplicant, what's left of the patch? All you need to do is put a PKCS#11 URI into the client-cert and private-key fields instead of a filename. All that remains is to ensure that the private-key-password is correctly handled and passed to wpa_supplicant, yes?
I tested again today. With the current version of wpa_supplicant, PKCS#11 Just Works™. With just this in wpa_supplicant.conf, it uses the correct key: client_cert="pkcs11:id=%4b%1a%cd%46%22%c4%a0%37%da%8a%3d%c5%b9%7e%f7%4f" private_key="pkcs11:id=%4b%1a%cd%46%22%c4%a0%37%da%8a%3d%c5%b9%7e%f7%4f" However, if I attempt to just set those values as the 802-1x.private-key and 802-1x.client-cert it fails because it's assuming that URI is a filename: Error: failed to modify 802-1x.client-cert: Failed to open file 'pkcs11:id=%4b%1a%cd%46%22%c4%a0%37%da%8a%3d%c5%b9%7e%f7%4f': No such file or directory. Thankfully our "validation" of certificates is inconsistent. Because if I do the equivalent for OpenConnect VPN, it *does* work and just silently passes through the URI string. I believe it also works for OpenVPN. So... to make this work for nmcli users, all we need to do is fix the validation of those strings. Allowing it to be configured in the GUI is next, and for that we need this year's GSoC project from bug 679860. And we need to work out how the PIN handling works. Encoding it in the URI can work for now, but we really want to sort out a common callback mechanism to ask for it on demand...
Closing this. We now handle 'pkcs11' scheme for 802.1x and since bug 778456 we deal with PINs too. What's left is the UI; but nmcli can be used.