Content:
3. Downloading, compiling, and installing the last stable release of OpenSC and HSM code
4. Initializing the device (setting the PINs)
5. Generating 521-bit EC key pair
6. Using the USB token as OpenSSL PKCS#11 engine
8. Importing X.509 certificate to the token storage
1. Introduction
In the modern cryptographic systems, the use of Elliptic Curve cryptography (ECC) becomes de facto a standard. Meanwhile, even now (it is 2019), it is quite rare to find a cryptographic token that supports the generation and use of ECDSA keys, up to 512 bits, SHA512 hash function (embedded in the processor of the token), and comes with a driver for Linux OS support. Most of the available tokens support mostly RSA key pairs, and even if they support ECDSA, that support is partial and the maximum key size is limited bellow 512 bits.
Surprisingly, you can find a reliable crypto token, that supports ECDSA 512-bit keys and SHA512 at:
The SmartCard-HSM 4K USB-Token, they have in sale, is supported by the driver library libccid.so, which is part of the OpenSC package (version 0.16 or higher). If one can download, compile, and install locally both the latest OpenSC and HSM code release, that is sufficient to employ the SmartCard-HSM 4K USB-Token in OpenSSL (as an engine), Mozilla Firefox, and Mozilla Thunderbird (as a security device).
The notes given bellow explain how to make the SmartCard-HSM 4K USB-Token device available in a Linux-based system running CentOS 7, Scientific Linux 7, Red Hat Enterprise Linux 8, and (possibly) Red Hat Enterprise Linux 8, how initializing the device, and the modules to interact the opensc tools (like pkcs11-tools and pkcs15-tools).
2. Connecting the device
Install the following packages (there is a good chance they are already installed):
# yum install pcsc pcsc-lite-ccid opensc
Enable the daemon pcscd to be loaded when starting/restarting the system:
# systemctl enable pcscd
and run it manually afterwards:
# systemctl start pcscd
Now you can connect the SmartCard-HSM 4K USB-Token device to the system. Records like those given bellow will be added to the /var/log/messages by syslog:
May 10 15:00:06 argus kernel: usb 3-10: new full-speed USB device number 9 using xhci_hcd May 10 15:00:06 argus kernel: usb 3-10: New USB device found, idVendor=04e6, idProduct=5816 May 10 15:00:06 argus kernel: usb 3-10: New USB device strings: Mfr=1, Product=2, SerialNumber=5 May 10 15:00:06 argus kernel: usb 3-10: Product: uTrust 3512 SAM slot Token May 10 15:00:06 argus kernel: usb 3-10: Manufacturer: Identiv May 10 15:00:06 argus kernel: usb 3-10: SerialNumber: 55511247701280
Their appearance there does not exactly mean the device is accessible by the applications. It only indicates that the USB device is properly recognized by libusb. In addition, the device will appear under the Vendor Name: SCM Microsystems, Inc., Vendor ID: 04e6, and Product ID: 5816, in the output generated by the execution of lsusb:
Bus 003 Device 009: ID 04e6:5816 SCM Microsystems, Inc.
If detailed debugging information, regarding the process of device detection, performed by pcscd daemon, is required, do modify the content of the file /usr/lib/systemd/system/pcscd.service (used by systemd to invoke the daemon pcscd), by adding the additional declaration --debug to the end of the line starting with "ExecStart":
ExecStart=/usr/sbin/pcscd --foreground --auto-exit --debug
Save the changes to the file, load the new list of declarations:
# systemctl daemon-reload
and finally restart the daemon pcscd:
# systemctl restart pcscd
At that moment, start monitoring the new content appended to the file /var/log/messages (# tailf /var/log/messages will do), then unplug and plug in the device, and watch what kind of messages the syslog daemon is appending to the file.
To prevent the fast growth of the /var/log/messages size on the disk, immediately after finishing with the analysis of the debug information, do restore the original declarations in /usr/lib/systemd/system/pcscd.service (remove the additional declaration --debug), reload it, and restart the daemon pcscd!
3. Downloading, compiling, and installing the last stable release of OpenSC and HSM code
First, install the required RPM packages (if they are not already installed):
# yum install git gcc gcc-c++ make
Then fetch the code of sc-hsm-embedded project, hosted on Github, configure, compile, and install it (change the destination folder after --prefix, if needed):
$ git clone https://github.com/CardContact/sc-hsm-embedded.git $ cd sc-hsm-embedded $ ./configure --prefix=/usr/local/sc-hsm-embedded $ make $ sudo make install
General note: Red Hat Enterprise Linux 8 (as well as CentOS 8 and Scientific Linux 8), ships OpenSC version 0.19. That means one does not need to compile OpenSC code, as explained bellow, in systems running EL8.
Once the installation is successfully completed, download, compile, and install the latest stable release of the OpenSC code (change the destination folder after --prefix and --with-completiondir, if needed):
$ wget https://github.com/OpenSC/OpenSC/releases/download/0.19.0/opensc-0.19.0.tar.gz $ tar xvf opensc-0.19.0.tar.gz $ cd opensc-0.19.0 $ ./configure --prefix=/usr/local/opensc-0.19.0 --with-completiondir=/usr/local/opensc-0.19.0/share/bash-completion/completions $ make $ sudo make install
The next step is to add the folders containing the installed binaries and libraries to the user's PATH and LD_LIBRARY_PATH environmental variables. Those additions can be made either system-wide (available to all users, inclusive) or user-specific (available only to specific users, exclusive):
-
system-wide:
Write down the following export declarations:
export PATH=/usr/local/opensc-0.19.0/bin:$PATH export LD_LIBRARY_PATH=/usr/local/sc-hsm-embedded/lib:/usr/local/opensc-0.19.0/lib:$LD_LIBRARY_PATH
to the file
/etc/profile.d/opensc.sh(create the file, it does not exist by default there). -
user-specific:
Open each
~/.bashrcfile and append (to the end) the following lines:export PATH=/usr/local/opensc-0.19.0/bin:$PATH export LD_LIBRARY_PATH=/usr/local/sc-hsm-embedded/lib:/usr/local/opensc-0.19.0/lib:$LD_LIBRARY_PATH
4. Initializing the device (setting the PINs)
The SmartCard-HSM 4K USB-Token device comes uninitialized! That means the device cannot be used, unless complete the initialization process first.
Connect the token to the system and invoke the tool sc-hsm-tool by specifying the SO PIN (SO stands for "Security Officer", change SO PIN 3537363231383830, specified in the example bellow, with another unique 16-digit long decimal number and do not forget it) and the user's PIN (change 123456 to another number):
$ sc-hsm-tool --initialize --so-pin 3537363231383830 --pin 123456
Here, the number after --so-pin is the SO PIN and the one after --pin is the user's PIN. Note that the SO PIN is the most important PIN, for it allows write access to the all slots of the device storage. Also, it can change every PUK and PIN, previously stored there (that includes the SO PIN itself). So do not loose SO PIN number!
5. Generating 521-bit EC key pair
Invoke the tool pkcs11-tool and specify the key type (EC:specp521r1 for 521-bit EC encryption key) and key pair ID label (it helps later to access the keys):
$ pkcs11-tool --module libsc-hsm-pkcs11.so -l --keypairgen --key-type EC:secp521r1 --id 10 --label "EC pair ID 10"
The user's PIN will be requested next, to grant access to the device storage and processor:
Enter PKCS#11 token PIN for SmartCard-HSM:
If the provided user's PIN is correct, it will take up to 2-3 seconds to execute and complete the key generation process.
The most important part of the command line above is the ID number assigned to the key pair (given above is 10, but you may reserve some other number, including hexadecimal number syntax, which is not already taken), because from that moment onward, the keys of that pair can be selected and involved in operations only if their ID number is specified.
6. Using the USB token as OpenSSL PKCS#11 engine
Install the package openssl-pkcs11 to enable the OpenSSL PKCS#11 engines functionality:
# yum install openssl-pkcs11
After that, store the following minimal OpenSSL configuration into a local file (openssl_hsm.cnf, for the sake of our illustration process):
openssl_conf = openssl_def [openssl_def] engines = engine_section [engine_section] pkcs11 = pkcs11_section [pkcs11_section] engine_id = libsc-hsm-pkcs11 dynamic_path = /usr/lib64/engines-1.1/pkcs11.so MODULE_PATH = /usr/local/opensc-0.19.0/lib/libsc-hsm-pkcs11.so init = 0 [ req ] distinguished_name = req_distinguished_name string_mask = utf8only [ req_distinguished_name ]
The only declaration in openssl_hsm.cnf one might need to change is that of MODULE_PATH:
MODULE_PATH = /usr/local/opensc-0.19.0/lib/libsc-hsm-pkcs11.so
Replace /usr/local/opensc-0.19.0 there with the actual folder, where the file libsc-hsm-pkcs11.so is stored. Note that the file is brought there during the installation of the HSM code).
7. Generating CSR, based on a key pair previously stored in the token, through OpenSSL PKCS#11 engine
If the OpenSSL PKCS#11 engine configuration file is available, the generation of CSR PKCS#10 block requires to specify the key pair ID (that is the number assigned to the key pair during the process of key pair generation):
$ openssl req -new -subj "/CN=server.example.com" -out request.pem -sha512 -config openssl_hsm.cnf -engine pkcs11 -keyform engine -key 10
One can expand both command line arguments and the set of declarations stored in openssl_hsm.cnf, if the CSR should contain some specific extensions, requested by the certificate issuer.
8. Importing X.509 certificate to the token storage
That type of operation is possible only if the X.509 certificate is stored in DER format (binary). For example, if the file SU_ECC_Root_CA.crt contains PEM formatted X.509 certificate, that certificate might be converted into DER format, by using openssl:
$ openssl x509 -in SU_ECC_Root_CA.crt -outform DER -out SU_ECC_Root_CA.der
To import the DER formatted X.509 certificate to the USB storage token, use the tool pkcs11-tool:
$ pkcs11-tool --module ibsc-hsm-pkcs11.so --login --write-object SU_ECC_Root_CA.der --type cert --id `uuidgen | tr -d -` --label "SU_ECC_ROOT_CA"
The label string after --label, naming the X.509 certificate, should be specified in a way hinting the purpose of having and using that certificate.





