|
Packit Service |
2ea82d |
# Build state
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
[![Linux Build Status](https://travis-ci.org/OpenSC/libp11.png)](https://travis-ci.org/OpenSC/libp11)
|
|
Packit Service |
2ea82d |
[![Windows Build status](https://ci.appveyor.com/api/projects/status/kmbu8nex5ogecoiq?svg=true)](https://ci.appveyor.com/project/LudovicRousseau/libp11)
|
|
Packit Service |
2ea82d |
[![Coverity Scan Status](https://scan.coverity.com/projects/15472/badge.svg)](https://scan.coverity.com/projects/opensc-libp11)
|
|
Packit Service |
2ea82d |
[![Code Quality: Cpp](https://img.shields.io/lgtm/grade/cpp/g/OpenSC/libp11.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/libp11/context:cpp)
|
|
Packit Service |
2ea82d |
[![Total Alerts](https://img.shields.io/lgtm/alerts/g/OpenSC/libp11.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSC/libp11/alerts)
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
# Overview
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
This code repository produces two libraries:
|
|
Packit Service |
2ea82d |
* libp11 provides a higher-level (compared to the PKCS#11 library)
|
|
Packit Service |
2ea82d |
interface to access PKCS#11 objects. It is designed to integrate with
|
|
Packit Service |
2ea82d |
applications that use OpenSSL.
|
|
Packit Service |
2ea82d |
* pkcs11 engine plugin for the OpenSSL library allows accessing
|
|
Packit Service |
2ea82d |
PKCS#11 modules in a semi-transparent way.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
The wiki page for this project is at https://github.com/OpenSC/libp11/wiki
|
|
Packit Service |
2ea82d |
and includes a bug tracker and source browser.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## PKCS#11
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
The PKCS#11 API is an abstract API to perform operations on cryptographic objects
|
|
Packit Service |
2ea82d |
such as private keys, without requiring access to the objects themselves. That
|
|
Packit Service |
2ea82d |
is, it provides a logical separation of the keys from the operations. The
|
|
Packit Service |
2ea82d |
PKCS #11 API is mainly used to access objects in smart cards and Hardware or Software
|
|
Packit Service |
2ea82d |
Security Modules (HSMs). That is because in these modules the cryptographic keys
|
|
Packit Service |
2ea82d |
are isolated in hardware or software and are not made available to the applications
|
|
Packit Service |
2ea82d |
using them.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
PKCS#11 API is an OASIS standard and it is supported by various hardware and software
|
|
Packit Service |
2ea82d |
vendors. Usually, hardware vendors provide a PKCS#11 module to access their devices.
|
|
Packit Service |
2ea82d |
A prominent example is the OpenSC PKCS #11 module which provides access to a variety
|
|
Packit Service |
2ea82d |
of smart cards. Other libraries like NSS or GnuTLS already take advantage of PKCS #11
|
|
Packit Service |
2ea82d |
to access cryptographic objects.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## OpenSSL engines
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
OpenSSL implements various cipher, digest, and signing features and it can
|
|
Packit Service |
2ea82d |
consume and produce keys. However plenty of people think that these features
|
|
Packit Service |
2ea82d |
should be implemented in separate hardware, like USB tokens, smart cards or
|
|
Packit Service |
2ea82d |
hardware security modules. Therefore OpenSSL has an abstraction layer called
|
|
Packit Service |
2ea82d |
"engine" which can delegate some of these features to different piece of
|
|
Packit Service |
2ea82d |
software or hardware.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
engine_pkcs11 tries to fit the PKCS#11 API within the engine API of OpenSSL.
|
|
Packit Service |
2ea82d |
That is, it provides a gateway between PKCS#11 modules and the OpenSSL engine API.
|
|
Packit Service |
2ea82d |
One has to register the engine with OpenSSL and one has to provide the
|
|
Packit Service |
2ea82d |
path to the PKCS#11 module which should be gatewayed to. This can be done by editing
|
|
Packit Service |
2ea82d |
the OpenSSL configuration file, by engine specific controls,
|
|
Packit Service |
2ea82d |
or by using the p11-kit proxy module.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
The p11-kit proxy module provides access to any configured PKCS #11 module
|
|
Packit Service |
2ea82d |
in the system. See [the p11-kit web pages](http://p11-glue.freedesktop.org/p11-kit.html)
|
|
Packit Service |
2ea82d |
for more information.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
# PKCS #11 module configuration
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Copying the engine shared object to the proper location
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
OpenSSL has a location where engine shared objects can be placed
|
|
Packit Service |
2ea82d |
and they will be automatically loaded when requested. It is recommended
|
|
Packit Service |
2ea82d |
to copy the engine_pkcs11 to that location as "libpkcs11.so" to ease usage.
|
|
Packit Service |
2ea82d |
This is handle by 'make install' of engine_pkcs11.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Using the engine from the command line
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
In systems with p11-kit-proxy engine_pkcs11 has access to all the configured
|
|
Packit Service |
2ea82d |
PKCS #11 modules and requires no further OpenSSL configuration.
|
|
Packit Service |
2ea82d |
In systems without p11-kit-proxy you need to configure OpenSSL to know about
|
|
Packit Service |
2ea82d |
the engine and to use OpenSC PKCS#11 module by the engine_pkcs11. For that you
|
|
Packit Service |
2ea82d |
add something like the following into your global OpenSSL configuration file
|
|
Packit Service |
2ea82d |
(often in ``/etc/ssl/openssl.cnf``). This line must be placed at the top,
|
|
Packit Service |
2ea82d |
before any sections are defined:
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
openssl_conf = openssl_init
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
This should be added to the bottom of the file:
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
[openssl_init]
|
|
Packit Service |
2ea82d |
engines=engine_section
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
[engine_section]
|
|
Packit Service |
2ea82d |
pkcs11 = pkcs11_section
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
[pkcs11_section]
|
|
Packit Service |
2ea82d |
engine_id = pkcs11
|
|
Packit Service |
2ea82d |
dynamic_path = /usr/lib/ssl/engines/libpkcs11.so
|
|
Packit Service |
2ea82d |
MODULE_PATH = opensc-pkcs11.so
|
|
Packit Service |
2ea82d |
init = 0
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
The dynamic_path value is the engine_pkcs11 plug-in, the MODULE_PATH value is
|
|
Packit Service |
2ea82d |
the OpenSC PKCS#11 plug-in. The engine_id value is an arbitrary identifier for
|
|
Packit Service |
2ea82d |
OpenSSL applications to select the engine by the identifier. In systems
|
|
Packit Service |
2ea82d |
with p11-kit-proxy installed and configured, you do not need to modify the
|
|
Packit Service |
2ea82d |
OpenSSL configuration file; the configuration of p11-kit will be used.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
If you do not update the OpenSSL configuration file you will need to
|
|
Packit Service |
2ea82d |
specify the engine configuration explicitly. The following line loads
|
|
Packit Service |
2ea82d |
engine_pkcs11 with the PKCS#11 module opensc-pkcs11.so:
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
OpenSSL> engine -t dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so
|
|
Packit Service |
2ea82d |
-pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD
|
|
Packit Service |
2ea82d |
-pre MODULE_PATH:opensc-pkcs11.so
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Testing the engine operation
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
To verify that the engine is properly operating you can use the following example.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
$ openssl engine pkcs11 -t
|
|
Packit Service |
2ea82d |
(pkcs11) pkcs11 engine
|
|
Packit Service |
2ea82d |
[ available ]
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Using p11tool and OpenSSL from the command line
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
This section demonstrates how to use the command line to create a self signed
|
|
Packit Service |
2ea82d |
certificate for "Andreas Jellinghaus". The key of the certificate will be generated
|
|
Packit Service |
2ea82d |
in the token and will not exportable.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
For the examples that follow, we need to generate a private key in the token and
|
|
Packit Service |
2ea82d |
obtain its private key URL. The following commands utilize p11tool for that.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
$ p11tool --provider /usr/lib/opensc-pkcs11.so --login --generate-rsa --bits 1024 --label test-key
|
|
Packit Service |
2ea82d |
$ p11tool --provider /usr/lib/opensc-pkcs11.so --list-privkeys --login
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
Note the PKCS #11 URL shown above and use it in the commands below.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
To generate a certificate with its key in the PKCS #11 module, the following commands commands
|
|
Packit Service |
2ea82d |
can be used. The first command creates a self signed Certificate for "Andreas Jellinghaus". The
|
|
Packit Service |
2ea82d |
signing is done using the key specified by the URL. The second command creates a self-signed
|
|
Packit Service |
2ea82d |
certificate for the request, the private key used to sign the certificate is the same private key
|
|
Packit Service |
2ea82d |
used to create the request. Note that in a PKCS #11 URL you can specify the PIN using the
|
|
Packit Service |
2ea82d |
"pin-value" attribute.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
$ openssl
|
|
Packit Service |
2ea82d |
OpenSSL> req -engine pkcs11 -new -key "pkcs11:object=test-key;type=private;pin-value=XXXX" \
|
|
Packit Service |
2ea82d |
-keyform engine -out req.pem -text -x509 -subj "/CN=Andreas Jellinghaus"
|
|
Packit Service |
2ea82d |
OpenSSL> x509 -engine pkcs11 -signkey "pkcs11:object=test-key;type=private;pin-value=XXXX" \
|
|
Packit Service |
2ea82d |
-keyform engine -in req.pem -out cert.pem
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Engine controls
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
The supported engine controls are the following.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
* **SO_PATH**: Specifies the path to the 'pkcs11-engine' shared library
|
|
Packit Service |
2ea82d |
* **MODULE_PATH**: Specifies the path to the pkcs11 module shared library
|
|
Packit Service |
2ea82d |
* **PIN**: Specifies the pin code
|
|
Packit Service |
2ea82d |
* **VERBOSE**: Print additional details
|
|
Packit Service |
2ea82d |
* **QUIET**: Do not print additional details
|
|
Packit Service |
2ea82d |
* **LOAD_CERT_CTRL**: Load a certificate from token
|
|
Packit Service |
2ea82d |
* **SET_USER_INTERFACE**: Set the global user interface
|
|
Packit Service |
2ea82d |
* **SET_CALLBACK_DATA**: Set the global user interface extra data
|
|
Packit Service |
2ea82d |
* **FORCE_LOGIN**: Force login to the PKCS#11 module
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
An example code snippet setting specific module is shown below.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
ENGINE_ctrl_cmd(engine, "MODULE_PATH",
|
|
Packit Service |
2ea82d |
0, "/path/to/pkcs11module.so", NULL, 1);
|
|
Packit Service |
2ea82d |
```
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
In systems with p11-kit, if this engine control is not called engine_pkcs11
|
|
Packit Service |
2ea82d |
defaults to loading the p11-kit proxy module.
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
# Developer information
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Thread safety in libp11
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
Thread-safety requires dynamic callbacks to be registered by the calling
|
|
Packit Service |
2ea82d |
application with the following OpenSSL functions:
|
|
Packit Service |
2ea82d |
* CRYPTO_set_dynlock_create_callback
|
|
Packit Service |
2ea82d |
* CRYPTO_set_dynlock_destroy_callback
|
|
Packit Service |
2ea82d |
* CRYPTO_set_dynlock_lock_callback
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
## Submitting pull requests
|
|
Packit Service |
2ea82d |
|
|
Packit Service |
2ea82d |
For adding new features or extending functionality in addition to the code,
|
|
Packit Service |
2ea82d |
please also submit a test program which verifies the correctness of operation.
|
|
Packit Service |
2ea82d |
See tests/ for the existing test suite.
|