This tool, which also comes with opensc, gives the user the option to provide a driver module. I.E. the module that exports the PKCS #11 functions. So as long as you have one of those suitable for your operating system, you can use this to access your token.
Actual results may differ though, while I have been able to do basic operations with the AEP Keyper for example, I did notice some minor faults in the tool, and in the drivers. Of course, these will be probably be fixed in the next version, where possible, I'll try to describe problems and workarounds for specific devices in the appendices.
For these examples we use the AEP Keyper, whose driver is called pkcs11.GCC4.0.2.so.4.04. See appendix A for more information about getting it running.
We have just initialized it as specified in the documentation.
% pkcs11-tool --module=/opt/lib/pkcs11.GCC4.0.2.so.4.04 -l -O Please enter User PIN: %
The -l option tells the tool to ask for the user PIN and log into the token if necessary. The -O switch asks the token for a list of objects, and prints some information about them.
Since we have just initialized the token, there is no information on it yet. So let's generate a key that we can use.
% pkcs11-tool --module=/opt/lib/pkcs11.GCC4.0.2.so.4.04 -l -k \ > -d 01 -a zone_key --key-type rsa:2048 Please enter User PIN: Key pair generated: Private Key Object; RSA label: zone_key ID: 01 Usage: decrypt, sign, unwrap Public Key Object; RSA 2048 bits label: zone_key ID: 01 Usage: encrypt, verify, wrap
Again, for this operation (as for most) we need to log in to the token, so we provide -l. Then we tell it to create a key pair (-k) with id 1 (-d hex) and label 'zone_key' (-a). We want the key to be of type RSA, with a modulus size of 2048 bits (-key-type).
As before, the program asks us for the token user's PIN and then starts generating the key. When it's done, it prints out some information about the created objects.
How you can make a backup of your keys, or move them to another token is out of scope for this document, but detailed instructions about this should be provided in the manual of the better HSM devices.
Some devices cannot create certain kinds of keys, for instance when they are too big, or when they would provide an operation that the device cannot support. In that case, this command will obviously fail.
Let's see whether it has really worked:
% pkcs11-tool --module=/opt/lib/pkcs11.GCC4.0.2.so.4.04 -l -O Please enter User PIN: Private Key Object; RSA label: zone_key ID: 01 Usage: decrypt, sign, unwrap
The label and id are as we previously specified. The label is just a string where you can place information about this specific key. The ID is a hexadecimal number that you use to specify this specific key when calling the application that needs to use it.
So, now that we have a key on there, we should be able to use any program that talks PKCS #11 to sign data. Here's one that does indirectly (through OpenSSL's EVP API).
% OPENSSL_CONF=~/aep_ssl_conf ldns-signzone -E pkcs11 \ > -k 1,5 nlnetlabs.nl Engine key id: 1, algo 5 PKCS#11 token PIN: %
This program itself is not relevant, except maybe that it signs data, but the way it works is. Through an environment variable we tell it to use a specific configuration file. That file adds the engine 'pkcs11' to the list of possible OpenSSL engines, and the driver we used previously. We talk more about this configuration file in section 4.1.
With that configuration file read, and OpenSSL adding the specified engines to its list, we tell the tool to use 'pkcs11', and 'key 1'. The ',5' is for the tool to know what to do with that exact key, and is not relevant here.