Signing files automatically using hardware token in Linux

I am currently doing some stuff for automatic signing of files for a friend of mine on a Linux machine (Ubuntu 19.10). Scary stuff. I know. The scenario is that the signing key is used in a script or similar in a controlled enviroment for some signing operations that are automated but using a certificate that is secured on a physical token such as the Safenet eToken 5100 or similar javabased keys. The end goal is to automate document signing for PDF.

It took alot of research and looking around before I could get if it was even possible. And it was actually pretty simple once I got the right drivers. Now, once I got it to work here the next step is to migrate it all to Windows and a PowerShell script but that is the next challenge.. =)

This is mostly done to make sure I can develop something cross-platform for PowerShell but before you can walk you need to crawl. So here is some pointers if some fool tries the same mission as I….. =)

First start by downloading the Safenet eToken 5100 token drivers.
Use the CORE drivers from withoutGUI folder.

Then install prereqs:

sudo apt install openssl
sudo apt install libssl-dev
sudo apt install safenetauthenticationclient-core_10.7.77_amd64.deb
sudo apt install libengine-pkcs11-openssl
sudo apt install opensc

After this plug in your token. It should light blue and stay blue when it is active. If the light goes out after a few seconds to a minute you need to do this:

sudo /usr/sbin/pcscd --foreground --auto-exit --apdu

Next step is to iterate the key and see the id of your signing key and any other certs in there (the “trust chain certs”):

pkcs11-tool --module /lib/libeToken.so --list-objects

Then I had to export all the certs, and then take all the “other” certs and concat them together to make a single file with the trust chain in it.

pkcs11-tool --module libeToken.so --read-object --type cert --id <certid> | openssl x509 -inform DER -outform PEM -out <cert.pem>

cat cert1.pem cert2.pem > chain.pem

Next step is to prepare the OpenSSL engine for use with this type and how to handle the key. The config file /etc/ssl/openssl.cnf was modified and the following content added:

#This line needs to be added in the "default" area, i.e. before any section
openssl_conf = openssl_def

[openssl_def]
engines = engine_section

[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
engine_id = pkcs11
#Make sure theese still works
dynamic_path = /usr/lib/x86_64-linux-gnu/engines-1.1/libpkcs11.so
MODULE_PATH = /lib/libeToken.so
# PIN for yor token!
PIN = 123456

And now comes the magic; testing signing using openssl:

openssl smime -md sha256 -binary -outform SMIME -sign -certfile <chain.pem> -signer <public.pem> -inkey slot_<slotid>-id_<certid> -keyform engine -in <inputfile> -out <outputfile> -engine pkcs11 -passin pass:<pincode>