- Make sure your hardware token is functioning on Linux
This is actually the tricky part in most cases. There are not that many hardware tokens
or smart cards available that work out of the box on Linux, and configuring the
driver and tools to use a hardware token can be difficult.
Install the pcscd, engine_pkcs11 and opensc packages, as they contain
necessary base utilities and tools. We will especially need the pkcs11-tool command from
the opensc package to store the certificate and private key on the hardware token.
- Copy the certificate and private key to the hardware token
Convert the certificate and private key files to DER format and copy them to the token:
$ cd /etc/ppp/keys
$ openssl x509 -in pptp-client.crt -outform der -out pptp-client-cert.der
$ pkcs11-tool --module /usr/lib64/libeTPkcs11.so --login --id 12345678 --type cert --w pptp-client-cert.der
$ openssl rsa -in pptp-client.key -outform der -out pptp-client-key.der
$ pkcs11-tool --module /usr/lib64/libeTPkcs11.so --login --id 12345678 --type privkey --w pptp-client-key.der
You can use the command
$ pkcs11-tool --module /usr/lib64/libeTPkcs11.so --login -O
to verify that the certificate and private key have been copied to the token. Afterwards you can and should
delete the .der files.
- Set up the /etc/ppp/openssl.cnf file
In order to use the engine_pkcs11 module with the patched pppd command a special
/etc/ppp/openssl.cnf file is needed. The path to this file is hardcoded into the pppd
binary for security reasons.
Create an /etc/ppp/openssl.cnf file as follows:
openssl_conf = openssl_def
[ openssl_def ]
engines = engine_section
[ engine_section ]
pkcs11 = pkcs11_section
[ pkcs11_section ]
engine_id = pkcs11
dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
MODULE_PATH = /usr/lib64/libeTPkcs11.so
init = 0
(for 32 bit systems adjust lib64 to lib).
It is also possible to hardcode the hardware token password (aka 'PIN') in this file using the
option:
PIN = XXXXXXX
NOTE: all keywords in the openssl.cnf file are case-sensitive!
- Specify the hardware token using command-line options
To connect to a pptpd server named 'pptp.example.com' using the certificate
and private key found on the hardware token in slot 0 with ID=12345678 you can use
./pppd file options-pptp-eaptls \
cert pkcs11:0:12345678 \
key pkcs11:0:12345678 \
ca /etc/ppp/keys/ca.crt \
pty "pptp pttp.example.com --nolaunchpppd"
The command will return immediately to the shell prompt.
Check the contents of the /tmp/pppd.log file to see the actual connection progress.
If all went well the bottom part of the /tmp/pppd.log file should list something like
local IP address 172.16.1.10
remote IP address 172.16.1.1
Script /etc/ppp/ip-up started (pid 29711)
Script /etc/ppp/ip-up finished (pid 29711), status = 0x0
NOTES:
- Checking the pppd.log connection log
A successful connection log file of a PPTP client with the certificate and private key
stored on a hardware token can be found here.
The most interesting parts are:
Found OpenSSL engine 'pkcs11'
Found engine identifier '39453945373335312d333545442d343031612d384637302d3238463636393036363042303a30'
Locating OpenSSL config file
Loading OpenSSL config file
Loading OpenSSL built-ins
Loading OpenSSL configured modules
Enabling OpenSSL auto engines
Loading OpenSSL 'pkcs11' engine support
Initialising engine
Loading private key '39453945373335312d333545442d343031612d384637302d3238463636393036363042303a30' from engine
Got the private key, adding it to SSL context
and yes, in this case the ID of the certificate on the token was indeed
39453945373335312d333545442d343031612d384637302d3238463636393036363042303a30 :)