2017-12-01 17:25:14 +01:00
|
|
|
|
|
|
|
:experimental:
|
|
|
|
|
|
|
|
[[chap-Defensive_Coding-HSM]]
|
2018-02-08 13:08:40 +01:00
|
|
|
= Hardware Security Modules and Smart Cards
|
2017-12-01 17:25:14 +01:00
|
|
|
|
|
|
|
Hardware Security Modules (HSMs) are specialized hardware intended
|
|
|
|
to protect private keys on server systems. They store internally
|
|
|
|
the private keys (e.g., RSA keys), and provide access to operations
|
|
|
|
with the keys without exposing the keys. That access, is provided using
|
|
|
|
a standardized API, which across Fedora is PKCS#11.
|
|
|
|
|
|
|
|
Smart cards are small cards with a micro processor, often combined with a
|
|
|
|
USB reader resembling a USB stick. They are very similar in nature with
|
|
|
|
HSMs as they can also be used to protect private keys and are almost
|
|
|
|
universally accessed via the PKCS#11 API. The main distinguishers from HSMs
|
|
|
|
is their inferior performance and often, the available hardware protection mechanisms.
|
|
|
|
|
|
|
|
Typically a smart card or HSM relies on a shared library to provide functionality.
|
|
|
|
This shared library follows the PKCS#11 API and thus is often referred to as
|
|
|
|
a PKCS#11 module. In Fedora the `opensc`
|
|
|
|
shared module (`opensc-pkcs11.so`) can be used for the majority
|
|
|
|
of smart cards available in the market. By convention these modules are located
|
|
|
|
at `/usr/lib64/pkcs11`. They can be used directly, or via
|
|
|
|
a higher level library.
|
|
|
|
|
|
|
|
All the major crypto libraries (NSS, GnuTLS and OpenSSL in Fedora) support
|
|
|
|
hardware security modules and smart cards, by providing wrappers over the
|
|
|
|
PKCS#11 API. However, the level of support varies, as well as the ease of
|
|
|
|
use of such modules and its integration to the overall library API.
|
|
|
|
|
|
|
|
* The PKCS#11 API does provide an API to access HSMs or smart cards, but
|
|
|
|
does not provide any method of discovering which HSMs or smart cards are
|
|
|
|
available in the system. In Fedora and modules are registered via link:++https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html++[p11-kit
|
|
|
|
configuration files], stored at `/etc/pkcs11/modules/`. For applications using
|
|
|
|
`engine_pkcs11` or GnuTLS the registered modules are
|
|
|
|
available without further configuration. Other applications will have to load
|
|
|
|
the `p11-kit-proxy.so` module.
|
|
|
|
|
|
|
|
* Most crypto libraries support the link:++https://tools.ietf.org/html/rfc7512++[PKCS#11 URLs scheme]
|
|
|
|
to identify objects stored in an HSM, however that support is not yet universal.
|
|
|
|
Some support transparent usage of PKCS#11 objects, e.g., specifying
|
|
|
|
a PKCS#11 object instead of a file, while others require to use
|
|
|
|
specialized APIs for such objects.
|
|
|
|
|
|
|
|
* Objects stored in an HSM or smart card can be protected with a PIN. As such,
|
|
|
|
libraries typically require to set a PIN handling function for accessing private keys,
|
|
|
|
or the PIN can be passed along with a PKCS#11 URL and the pin-value parameter.
|
|
|
|
|
|
|
|
* Obtaining a Hardware Security Module, or including it on a continuous integration
|
|
|
|
testing is not always feasible. For testing purposes smart cards supported by the OpenSC
|
|
|
|
project can be used, as well as software modules like `softhsm` which
|
|
|
|
provides a tool to setup a software HSM, and a PKCS#11 library.
|
|
|
|
|
|
|
|
* The PKCS#11 API requires applications that use fork to reinitialize the used PKCS#11
|
|
|
|
modules. This is an uncommon requirement, which has led to several bugs across
|
|
|
|
applications in Fedora which used PKCS#11 directly. To make things more complicated
|
|
|
|
software PKCS#11 module like `softhsm` do not require this re-initialization
|
|
|
|
leading to applications working against software modules but failing with hardware
|
2018-02-01 15:47:45 +01:00
|
|
|
modules or smart cards. The wrapper PKCS#11 APIs provided by NSS, GnuTLS and
|
2017-12-01 17:25:14 +01:00
|
|
|
engine_pkcs11 (OpenSSL) handle the reinitialization after fork requirement transparently.
|
|
|
|
|
|
|
|
[[sect-Defensive_Coding-HSM-OpenSSL]]
|
2018-02-08 13:08:40 +01:00
|
|
|
== OpenSSL HSM Support
|
2017-12-01 17:25:14 +01:00
|
|
|
|
|
|
|
OpenSSL does not have native support for PKCS#11. It can
|
|
|
|
provide PKCS#11 support through the OpenSC's project
|
|
|
|
`pkcs11` engine (formerly known as `engine_pkcs11`).
|
|
|
|
As such software intended to use HSMs, must utilize that engine.
|
|
|
|
|
|
|
|
Engine `pkcs11` supports loading stored objects via PKCS#11 URLs.
|
|
|
|
If no PKCS#11 module is specified the engine will use the system-wide registered
|
|
|
|
modules via `p11-kit-proxy.so`.
|
|
|
|
|
|
|
|
The following example demonstrates the initialization of the pkcs11 engine
|
|
|
|
and its usage to sign data.
|
|
|
|
|
|
|
|
[[ex-Defensive_Coding-HSM-OpenSSL]]
|
|
|
|
.Signing data with HSM and OpenSSL
|
|
|
|
====
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
[source,c]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
2018-09-20 11:29:31 +02:00
|
|
|
include::{partialsdir}/snippets/Features-HSM-OpenSSL.adoc[]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
|
|
|
====
|
|
|
|
|
|
|
|
[[sect-Defensive_Coding-HSM-GNUTLS]]
|
2018-02-08 13:08:40 +01:00
|
|
|
== GnuTLS HSM Support
|
2017-12-01 17:25:14 +01:00
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
GnuTLS supports PKCS#11 natively. Most of the API functions
|
2017-12-01 17:25:14 +01:00
|
|
|
accepting certificate files, can also accept PKCS#11 URLs, thus
|
|
|
|
requiring minor or no modifications to applications in order
|
|
|
|
to support HSMs. In most cases applications must be modified
|
|
|
|
to install a PIN callback function.
|
|
|
|
|
|
|
|
The following example demonstrates the initialization of the pkcs11 engine
|
|
|
|
and its usage to sign data.
|
|
|
|
|
|
|
|
[[ex-Defensive_Coding-HSM-GNUTLS]]
|
|
|
|
.Signing data with HSM and GnuTLS
|
|
|
|
====
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
[source,c]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
2018-09-20 11:29:31 +02:00
|
|
|
include::{partialsdir}/snippets/Features-HSM-GNUTLS.adoc[]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
|
|
|
====
|
|
|
|
|
|
|
|
The PIN callback function can be either set globally as in
|
|
|
|
the example above or locally by utilizing functions such as `gnutls_privkey_set_pin_function`.
|
|
|
|
An example PIN callback function is shown below.
|
|
|
|
|
|
|
|
[[ex-Defensive_Coding-HSM-GNUTLS-PIN]]
|
|
|
|
.An example PIN callback with GNUTLS
|
|
|
|
====
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
[source,c]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
2018-09-20 11:29:31 +02:00
|
|
|
include::{partialsdir}/snippets/Features-HSM-GNUTLS-PIN.adoc[]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
|
|
|
====
|
|
|
|
|
|
|
|
[[sect-Defensive_Coding-HSM-NSS]]
|
2018-02-08 13:08:40 +01:00
|
|
|
== NSS HSM Support
|
2017-12-01 17:25:14 +01:00
|
|
|
|
|
|
|
NSS supports PKCS#11 natively. In fact all NSS crypto operations,
|
|
|
|
including built-in operations, go through PKCS #11 modules. NSS provides
|
|
|
|
its own software PKCS #11 module called softoken. NSS automatically
|
|
|
|
loads any PKCS #11 module specified in its module database, which can
|
|
|
|
be manipulated with the modutil command. NSS uses the PKCS #11 module
|
|
|
|
that contains the requested keys to do the crypto operations. As long as
|
|
|
|
the application opens an NSS database and properly sets a pin callback. If
|
|
|
|
it runs with native NSS, it should be able to use HSMs that provide PKCS #11
|
|
|
|
modules. Modules can also be loaded programatically, though this is less common.
|
|
|
|
|
|
|
|
The following example demonstrates a typical NSS application for signing.
|
|
|
|
|
|
|
|
[[ex-Defensive_Coding-HSM-NSS]]
|
|
|
|
.Signing data with HSM and NSS
|
|
|
|
====
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
[source,c]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
2018-09-20 11:29:31 +02:00
|
|
|
include::{partialsdir}/snippets/Features-HSM-NSS.adoc[]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
|
|
|
====
|
|
|
|
|
|
|
|
To use the example above with an HSM or smart card you will need to do the following.
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
[source,bash]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
|
|
|
# add your HSM or token library to an NSS database (in the sample code the database is
|
|
|
|
# located in the current directory'.')
|
|
|
|
$ modutil -add "My HSM" -libfile ${path_to_pkcs11_file} -dbdir .
|
|
|
|
# Find the token name on your HSM
|
|
|
|
$ modutil -list -dbdir .
|
|
|
|
# find the cert on your token
|
|
|
|
$ certutil -L -h ${token_name} -d .
|
|
|
|
# pass the cert to your signing program
|
|
|
|
$ NSS_Sign_Example "${token_name}:${cert_name}"
|
2018-02-08 13:08:40 +01:00
|
|
|
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
|
|
|
[[ex-Defensive_Coding-HSM-NSS-PIN]]
|
|
|
|
.An example PIN callback with NSS
|
|
|
|
====
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
[source,c]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
2018-09-20 11:29:31 +02:00
|
|
|
include::{partialsdir}/snippets/Features-HSM-NSS-PIN.adoc[]
|
2017-12-01 17:25:14 +01:00
|
|
|
----
|
|
|
|
|
2018-02-01 15:47:45 +01:00
|
|
|
====
|