1) Setup a working/classic WiFi or wired 802.1x setup with EAP-TLS:
-------------------------------------------------------------------
For this I've used a WiFi access point, a laptop and a server which runs a Radius service.
On the laptop and server I've used Ubuntu 13.10. The laptop and WiFi access point model shouldn't matter too much.
I've used as laptop a Lenovo ThinkPad T420s and as WiFi access point a DrayTek Vigor 2820.

For someone who never did this kind of setup please refer to this pretty good tutorial:
http://cubicspot.blogspot.de/2013/04/setting-up-wpa2-enterprise-aes-with.html
Please note that you will need the client certificate in 'der' and 'pkcs12' format.
You will also need the private client key in 'pkcs8' format.

Once this setup works via a system-connection continue with step 2.
Here is my final 802-1x section of the system-connection on the laptop:
(as you can see I didn't bother to change any CA defaults for the test setup)

[802-1x]
eap=tls;
identity=test-user
ca-cert=/root/ca.pem
client-cert=/root/client.p12
private-key=/root/client.p12
private-key-password=whatever


2) Compile latest Network Manager from source, install it and test it:
----------------------------------------------------------------------
$ cd ~
$ sudo apt-get build-dep network-manager
$ sudo apt-get install git
$ git clone git://anongit.freedesktop.org/NetworkManager/NetworkManager
$ cd NetworkManager
'vapigen' gave me very weird errors on Ubuntu 13.10 and I couldn't figure out a solution for it
-> I've edited 'Makefile.am' and removed the 'vapi' directory for 'SUBDIRS'
$ ./autogen.sh && make clean && make
$ sudo make install

Stop the system's Network Manager and use the newly installed one. AppArmor has to be disabled or reconfigured for this!
$ sudo stop network-manager
$ sudo /etc/init.d/apparmor stop
$ sudo /etc/init.d/apparmor teardown
$ sudo cp /ect/NetworkManager/system-connections/* /usr/local/ect/NetworkManager/system-connections/
$ sudo LD_LIBRARY_PATH=/usr/local/lib /usr/local/sbin/NetworkManager --no-daemon -d

The new Network Manager should just work as before.


3) Apply the PKCS #11 Network Manager patch and retest:
-------------------------------------------------------
$ cd ~/NetworkManager
$ git apply nm-pkcs11.patch
$ make
$ sudo make install
$ sudo LD_LIBRARY_PATH=/usr/local/lib /usr/local/sbin/NetworkManager --no-daemon -d

The patched new Network Manager should just work as before.


4) Patch WPA supplicant to support settings the PKCS #11 engine and module path via the new D-Bus interface:
------------------------------------------------------------------------------------------------------------
Download the patch from http://w1.fi/bugz/show_bug.cgi?id=499 for your WPA supplicant package version.
The package version can be determined by running 'dpkg -s wpasupplicant | grep Version'.

$ sudo apt-get build-dep wpasupplicant
$ sudo apt-get install build-essential devscripts quilt

$ cd ~
$ mkdir pkg
$ cd pkg
$ apt-get source wpa
$ cd wpa*
$ quilt import wpas-pkcs11.patch
$ quilt push -a
$ quilt refresh
$ dch -i
Enter as changelog description "Test build"
$ dpkg-buildpackage

Once the package build succeeds install it, kill the current wpa_supplicant process and retest:
$ sudo dpkg -i ../wpasupplicant_*.deb
$ sudo killall wpa_supplicant
$ sudo LD_LIBRARY_PATH=/usr/local/lib /usr/local/sbin/NetworkManager --no-daemon -d

The patched new Network Manager and WPA supplicant should just work as before.


5) Setup SoftHSM to test the new PKCS #11 support in Network Manager:
---------------------------------------------------------------------
Note: These instructions are NOT secure as the private key is NOT securely stored!

$ sudo apt-get install libengine-pkcs11-openssl softhsm opensc
$ sudo softhsm --init-token --slot 0 --label "Software Token" --so-pin 111111 --pin 000000

$ Import certificate:
sudo pkcs11-tool --module /usr/lib/softhsm/libsofthsm.so --login --pin 000000 --slot 0 --id 00 --write-object /root/client.der --type cert --label "Radius Client Certificate"

Import private key in pkcs8 format:
$ sudo softhsm --pin 000000 --slot 0 --id 00 --import /root/client.p8 --label "Radius Client Certificate"

Check if everything worked:
$ sudo pkcs11-tool --module /usr/lib/softhsm/libsofthsm.so --login --pin 000000 --slot 0 -O
Public Key Object; RSA 2048 bits
  label:      Radius Client Certificate
  ID:         00
  Usage:      verify
Private Key Object; RSA 
  label:      Radius Client Certificate
  ID:         00
  Usage:      sign
Certificate Object, type = X.509 cert
  label:      Radius Client Certificate
  ID:         00


6) Change 802.1x config to use the PKCS #11 OpenSSL engine:
-----------------------------------------------------------
New config:
[802-1x]
eap=tls;
identity=test-user
ca-cert=/root/ca.pem
engine=1
pin=000000
key-id=slot_0-id_00
cert-id=slot_0-id_00
pkcs11-engine-path=/usr/lib/engines/engine_pkcs11.so
pkcs11-module-path=/usr/lib/softhsm/libsofthsm.so

$ sudo LD_LIBRARY_PATH=/usr/local/lib /usr/local/sbin/NetworkManager --no-daemon -d

The patched new Network Manager and WPA supplicant should just work as before.



