blob: eab7bdfbc2e14c6d006ae86881d46add52804a2e [file] [log] [blame]
PKCS11 Token support for openssl keys
=====================================
This system is designed to build a PKCS11 token library
(openssl-pkcs11.so) which is usable by any PKCS11 accepting program
(like p11-kit, libp11 or ssh). It has mostly been tested with p11-kit
and the pkcs11 engine of openssl.
Architecture
------------
Architecturally, PKCS11 has one shared object that drives multiple
"slots" which may or may not be populated with "tokens", but which may
only have zero or one token. Each token may have multiple objects, of
which one type is key. Each key has a public component, viewable
without logging into the token and a private component which can only
be used if the token has been logged into. The login occurs at the
token level, so every object in the token is unlocked by the single
token login event.
Openssl has public and private key files. Public key files are
technically unnecessary because the private key files contain all the
data. However if a private key file is locked with a password, all
the data, including the public parts is encyrpted. Since a token is
required to show public data without requiring a login, *both* the
public and private openssl keys must be specified to build the token.
Further, since it is impossible to know if key files have identical
passwords, the mapping paradigm is going to have to be one
public/private key pair per token, meaning each token in the openssl
engine will have two and only two key objects.
Configuration
-------------
Each key pair token must be configured. By default this is with a file in your home directory under
${HOME}/.config/openssl-pkcs11/openssl-pkcs11.conf
But the file may be overridden by setting the OPENSSL_PKCS11_CONF
environment variable to point to the config file.
The configuration file is a classic ini file format. It has a global
section which sets the library manufacturere and description with
manufacturer id = <string>
library description = <string>
However, these aren't necessary: they will show up in p11-kit
list-modules, but they're not part of the token URIs.
Keys are specified as
[<key token name>]
private key = <full path to private key>
public key = <full path to public key>
And the following are optional and add to the token parameters
id = <id>
label = <label>
Optional parameters are
serial = <serial number>
If you don't fill this in the serial number will be a hex string of
the first 10 bytes of the sha256 sum of the public key.
And finally, if your key is rooted in an openssl engine you need to
add this optional parameter:
engine = <engine name>
Using the Token Library
-----------------------
The token library by default installs itself in the p11-kit modules
directory, so the way to use it is via thinks that understand the
p11-kit token URI, like gnutls or openssl with the pkcs11 engine (from
libp11). Although you can get the exact token URIs by doing
p11tool --list-all pkcs11:manufacturer=openssl-pkcs11
You can abbreviate the URI somewhat by dropping the model= and id= and object= components because each token we create has a single public-private key pair. So if you have a key defined as
[mykey]
id = something
public key = /path/to/key.pub
private key = /path/to/key.priv
You can simply refer to both the public and private keys by the single URI
'pkcs11:manufacturer=openssl-pkcs11;token=mykey'
(remembering always to quote the URI because it contains the shell
special parameter ;) because tools that use p11-kit will search the
token and find a single key. For non-p11-kit based tools you may have
to add at least the object qualifier because the above URI would be
inexact for tokens with more than one key pair.
So, for example, you should be able to create a rsa signature from a
short file tmp.txt using openssl and the libp11 pkcs11 engine with:
openssl rsautl -sign -engine pkcs11 -keyform engine -in tmp.txt -inkey 'pkcs11:manufacturer=openssl-pkcs11;token=mykey' -out tmp.sig
Note that due to a mismatch in the way the APIs work, it is not
possible to have a pkcs11 library not request a PIN. If your key has
no password, simply enter a dummy pin. If your key does have a
password, then that is the pin.
Note also that PKCS11 requires pins to be between 4 and 32 characters.
If your key password doesn't satisfy this, you won't be able to use
the key.