- Notifications
You must be signed in to change notification settings - Fork194
OpenSC/libp11
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This code repository provides three libraries:
- libp11 – Provides a higher-level interface (compared to the PKCS#11 library)for accessing PKCS#11 objects. It is designed to integrate with applicationsthat use OpenSSL.
- pkcs11prov – An OpenSSL 3.x provider plugin that allows transparent access toPKCS#11 modules.
- pkcs11 – A legacy OpenSSL engine plugin that allows semi-transparent accessto PKCS#11 modules.
The wiki page for this project is available athttps://github.com/OpenSC/libp11/wiki. It includes a bug tracker and sourcebrowser.
The PKCS#11 API is an abstract API to perform operations on cryptographicobjects such as private keys, without requiring access to the objectsthemselves. That is, it provides a logical separation of the keys from theoperations. The PKCS#11 API is mainly used to access objects in smart cards andhardware or software security modules (HSMs). In these modules, cryptographickeys are isolated and not made available to applications.
The PKCS#11 API is an OASIS standard and is supported by various hardware andsoftware vendors. Hardware vendors usually provide a PKCS#11 module to accesstheir devices. A prominent example is the OpenSC PKCS#11 module which providesaccess to a variety of smart cards. Other libraries, such as NSS and GnuTLS,already take advantage of PKCS#11 to access cryptographic objects.
For further integration with multiple PKCS#11 modules, thep11-kit proxy module canbe used in conjunction with the pkcs11prov provider and the pkcs11 engine,allowing access to all PKCS#11 modules configured on the system.
With OpenSSL 3.x, the architecture has been redesigned to use a provider-basedmodel. In this model, most cryptographic algorithms and related functionalityare implemented in providers, which are dynamically loadable modules. Providerscan supply implementations of ciphers, digests, key management, and relatedoperations.
Thepkcs11prov provider is designed to bridge the OpenSSL providerinterface and the PKCS#11 API. This enables applications using OpenSSL 3.x totransparently access cryptographic operations and objects managed by PKCS#11modules, such as those found in smart cards, USB tokens, and hardware securitymodules. The provider registers itself with OpenSSL, and the specific PKCS#11module to be used is typically specified in the OpenSSL configuration file orvia provider-specific parameters.
By using the pkcs11prov provider, applications can perform cryptographicoperations using keys stored in external hardware, without requiring changes toapplication code.
OpenSSL implements various cipher, digest, and signing features and it canconsume and produce keys. However, many people believe that these featuresshould be implemented in separate hardware, such as USB tokens, smart cards, orhardware security modules. Therefore, OpenSSL includes an abstraction layercalled an "engine", which can delegate some of these features to differentpieces of software or hardware.
Thepkcs11 engine integrates the PKCS#11 API within the OpenSSL engine API.That is, it provides a gateway between PKCS#11 modules and the OpenSSL engineAPI. The engine must be registered with OpenSSL, and the path to the PKCS#11module, which will perform cryptographic operations, must be specified. Thiscan be done by editing the OpenSSL configuration file or using engine-specificcontrols.
The provider supports most of the PKCS#11 URI format defined byRFC 7512.
OpenSSL has a designated location where provider shared objects can be placedto allow automatic loading. To simplify usage, it is recommended to copypkcs11prov to that location aspkcs11prov.so.
The provider location can be displayed with:
openssl version -mmake install in libp11 handles provider installation.
OpenSSL 3.x does not automatically load custom providers, soopenssl.cnf mustexplicitly define them. Without this configuration, OpenSSL will not detect orloadpkcs11prov.
[openssl_init]providers = provider_sect[provider_sect]default = default_sectpkcs11 = pkcs11_sect[default_sect]activate = 1[pkcs11_sect]identity = pkcs11provmodule = /usr/lib64/ossl-modules/pkcs11prov.sopkcs11_module = /usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.sodebug_level = 7force_login = 1pin = XXXXactivate = 1Some parameters can be overridden using environment variables:OPENSSL_MODULES,PKCS11_MODULE_PATH,PKCS11_DEBUG_LEVEL,PKCS11_FORCE_LOGIN,PKCS11_PIN
To verify correct provider operation, run the following command:
$ openssl list -providers -verbose -provider pkcs11provProviders: pkcs11prov name: libp11 PKCS#11 provider (pkcs11prov) version: 3.4.1 status: active build info: 3.4.1 gettable provider parameters: name: pointer to a UTF8 encoded string (arbitrary size) version: pointer to a UTF8 encoded string (arbitrary size) buildinfo: pointer to a UTF8 encoded string (arbitrary size) status: integer (arbitrary size)To enable automatic provider loading, ensure youropenssl.cnf includes thefollowing:
openssl_conf = openssl_init[openssl_init]providers = provider_sect[provider_sect]default = default_sectpkcs11 = pkcs11_sect[default_sect]activate = 1[pkcs11_sect]identity = pkcs11provpkcs11_module = /usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.soactivate = 1To generate a certificate with its key stored in the PKCS#11 module, use thefollowing:
$ openssl req -new -key "pkcs11:object=test-key;type=private;pin-value=XXXX" \ -out req.pem -text -x509 -subj "/CN=Andreas Jellinghaus"$ openssl x509 -signkey "pkcs11:object=test-key;type=private;pin-value=XXXX" \ -in req.pem -out cert.pemAlternatively, use environment variables:
$ PKCS11_MODULE_PATH=/usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so PKCS11_PIN=XXXX \ openssl req -new -key "pkcs11:object=test-key;type=private" \ -out req.pem -text -x509 -subj "/CN=Andreas Jellinghaus" \ -provider pkcs11prov -provider default$ PKCS11_MODULE_PATH=/usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so PKCS11_PIN=XXXX \ openssl x509 -signkey "pkcs11:object=test-key;type=private" \ -in req.pem -out cert.pem \ -provider pkcs11prov -provider defaultThe provider supports the following controls:
- pkcs11_module: Specifies the path to the PKCS#11 module shared library
- pin: Specifies the PIN
- debug_level: Sets the debug level: 0=emerg, 1=alert, 2=crit, 3=err,4=warning, 5=notice (default), 6=info, 7=debug
- force_login: Forces login to the PKCS#11 module
- init_args: Specifies additional initialization arguments to the PKCS#11module
Example code snippet for setting a specific module (requires OpenSSL 3.5):
OSSL_PROVIDER *provider=OSSL_PROVIDER_load(NULL, "pkcs11prov");OSSL_PROVIDER_add_conf_parameter(provider, "pkcs11_module","/path/to/pkcs11module.so");OpenSSL has a designated location where engine shared objects can be placed,and they will be automatically loaded when requested. It is recommended tocopy the pkcs11 engine to that location aslibpkcs11.so to simplify usage.
The engine location can be displayed with:
openssl version -emake install in libp11 handles engine installation.
On systems with p11-kit-proxy, the pkcs11 engine has access to all theconfigured PKCS#11 modules and requires no further OpenSSL configuration. Insystems without p11-kit-proxy, you need to configure OpenSSL to recognize theengine and to use the OpenSC PKCS#11 module with the pkcs11 engine. Add thefollowing line to your global OpenSSL configuration file (often in/etc/ssl/openssl.cnf). Place this line at the top, before any sections aredefined:
openssl_conf = openssl_initAdd the following at the end of the file:
[openssl_init]engines=engine_section[engine_section]pkcs11 = pkcs11_section[pkcs11_section]engine_id = pkcs11dynamic_path = /usr/lib/x86_64-linux-gnu/engines-3/libpkcs11.soMODULE_PATH = opensc-pkcs11.soinit = 0Thedynamic_path value is the pkcs11 engine plug-in. TheMODULE_PATH valueis the OpenSC PKCS#11 plug-in. Theengine_id value is an arbitrary identifierfor OpenSSL applications to select the engine by the identifier. On systemswith p11-kit-proxy installed and configured, you do not need to modify theOpenSSL configuration file; the configuration of p11-kit will be used. If youdo not update the OpenSSL configuration file, you must specify the engineconfiguration explicitly. The following line loads the pkcs11 engine with thePKCS#11 module opensc-pkcs11.so:
OpenSSL> engine -t dynamic -pre SO_PATH:/usr/lib/x86_64-linux-gnu/engines-3/pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:opensc-pkcs11.soTo verify that the engine is properly operating, use the following example:
$ openssl engine pkcs11 -t(pkcs11) pkcs11 engine [ available ]This section demonstrates how to use the command line to create a self-signedcertificate for "Andreas Jellinghaus". The key of the certificate will begenerated in the token and will not be exportable.
For the examples that follow, we need to generate a private key in the tokenand obtain its private key URL. The following commands usep11tool for thispurpose.
$ p11tool --provider /usr/lib/opensc-pkcs11.so --login --generate-rsa --bits 1024 --label test-key$ p11tool --provider /usr/lib/opensc-pkcs11.so --list-privkeys --loginNote the PKCS#11 URL shown above and use it in the commands below.
To generate a certificate with its key in the PKCS#11 module, use the followingcommands. The first command creates a self-signed certificate for "AndreasJellinghaus". Signing is performed using the key specified by the URL. Thesecond command creates a self-signed certificate for the request, the privatekey used to sign the certificate is the same private key used to create therequest. Note that, in a PKCS#11 URL, you can specify the PIN using the"pin-value" attribute.
$ opensslOpenSSL> req -engine pkcs11 -new -key "pkcs11:object=test-key;type=private;pin-value=XXXX" \ -keyform engine -out req.pem -text -x509 -subj "/CN=Andreas Jellinghaus"OpenSSL> x509 -engine pkcs11 -signkey "pkcs11:object=test-key;type=private;pin-value=XXXX" \ -keyform engine -in req.pem -out cert.pemThe following engine controls are supported:
- SO_PATH: Specifies the path to the 'pkcs11-engine' shared library
- MODULE_PATH: Specifies the path to the pkcs11 module shared library
- PIN: Specifies the PIN
- DEBUG_LEVEL: Set the debug level: 0=emerg, 1=alert, 2=crit, 3=err,4=warning, 5=notice (default), 6=info, 7=debug
- QUIET: Do not print additional details
- LOAD_CERT_CTRL: Load a certificate from token
- SET_USER_INTERFACE: Set the global user interface
- SET_CALLBACK_DATA: Set the global user interface extra data
- FORCE_LOGIN: Force login to the PKCS#11 module
- RE_ENUMERATE: re-enumerate the slots/tokens, required whenadding/removing tokens/slots
- VLOG_A: Set the logging callback
The following example demonstrates how to set a specific module:
ENGINE_ctrl_cmd(engine, "MODULE_PATH",0, "/path/to/pkcs11module.so", NULL, 1);On systems with p11-kit, if this engine control is not called, the pkcs11 enginedefaults to loading the p11-kit proxy module.
libp11 internally uses OS locking, and configures the PKCS#11 module to dothe same.
Access to PKCS#11 tokens and objects is provided via a pool of PKCS#11sessions. This allows concurrent usage of crypto operations in a thread-safemanner.
When adding new features or extending functionality, please also submit a test program that verifies correct operation.
Refer to thetests/ directory for the existing test suite.
About
PKCS#11 wrapper library
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.