| 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. |