NetworkManager PKCS#11 Plan
Neither NetworkManager nor the various clients (nmcli, KDE, GNOME Shell, nmtui, nm-connection-editor, openvpn, openconnect) should handle certificate paths. Instead, when choosing certificates and keys for 802.1x authentication methods like TLS, TTLS, PEAP, and FAST, the user should be able to pick a certificate from an existing PKCS#11 hardware token or "soft" token/certificate store. To use a certificate, that certificate must exist in the token/store, or be imported in to the token/store before it can be used to authenticate to the network.
The first step is to ensure that PKCS#11 URIs are usable in all cases, without actually removing the ability to use certificates from a file.
The current status and work is being tracked in Bug 719982.
The implementation should be based around p11-kit, a project which makes using different PKCS#11 modules much simpler. The first main piece happens in the GUI clients, which must be modified to support certificate choosers, retrieve the PKCS#11 URI for that certificate or key, and pass that to NetworkManager. Then, NetworkManager is modified to pass the URI to p11-kit's "proxy" module.
- Add the "pkcs11-uri://" scheme prefix similar to what exists already for "file" and "blob". This scheme would contain the PKCS#11 URI returned by a certificate chooser.
- Helpers for the URI should be added, such as nm_setting_802_1x_get_client_cert_pkcs11_uri() and nm_setting_802_1x_set_client_cert_pkcs11_uri(), which does some minimal validation. verify() should also do some minimal validation on deserialized URIs.
The editor must preserve the certificate/key paths in existing connections, but changing any certificate/key should use a certificate chooser widget like the one provided by Gcr.
- Bonus points if the existing path-based certificates/keys could be imported into the certificate store and the path:// scheme replaces with pkcs11-uri:// with one button press.
- The editor must be modified to recognize that private keys specified with PKCS#11 URIs do not require private key passwords. When a key is chosen, the "Private Key Password" entry should be hidden.
- The agent in the desktop session should be able to talk p11-kit remoting protocol (e.g. by spawning "p11-kit remote") thorough a file descriptor a and send the descriptor to the daemon of daemon asks for one.
When an 802.1x-based connection or VPN connection is activated that includes PKCS#11 URIs, NetworkManager tries to look up the desktop agent agent and get a remoting fd
NetworkManager passes those PKCS#11 URIs along with the file handle to the p11-kit remote to the helper process via D-Bus (e.g "key_id", "ca_cert_id", "cert_id", "key2_id", "ca_cert2_id", and "cert2_id" parameters for the wpa_supplicant. With sufficiently capable versions of wpa_supplicant, there is no need to mess with explicit ENGINE configuration).
- If remoting is used, the p11-remote should deal with the PIN request. Otherwise, when needed, the token PIN would be retrieved with the usual Secret Agent mechanisms, passing "pin" as the hint.
There are some caveats to note around PIN handling:
Some tokens may require a PIN even to confirm the existence of a certificate, let alone its corresponding private key. See the Seahorse UI which allows us to log in to specific tokens... although it then doesn't rescan their contents after doing so, which it should.
Sometimes a PIN is required for each usage of the private key, and a PIN callback may be invoked each time it is needed.