179 lines
8.5 KiB
XML
179 lines
8.5 KiB
XML
<?xml version='1.0' encoding='utf-8' ?>
|
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
|
]>
|
|
<chapter id="chap-Defensive_Coding-HSM">
|
|
<title>Hardware Security Modules and Smart Cards</title>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<para>
|
|
Smart cards are small cards with a micro processor, often combined with a
|
|
USB reader ressembling 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.
|
|
</para>
|
|
<para>
|
|
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 <literal>opensc</literal>
|
|
shared module (<literal>opensc-pkcs11.so</literal>) can be used for the majority
|
|
of smart cards available in the market. By convention these modules are located
|
|
at <literal>/usr/lib64/pkcs11</literal>. They can be used directly, or via
|
|
a higher level library.
|
|
</para>
|
|
<para>
|
|
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.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
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 <ulink url="https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html">p11-kit
|
|
configuration files</ulink>, stored at <literal>/etc/pkcs11/modules/</literal>. For applications using
|
|
<literal>engine_pkcs11</literal> or GnuTLS the registered modules are
|
|
available without further configuration. Other applications will have to load
|
|
the <literal>p11-kit-proxy.so</literal> module.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Most crypto libraries support the <ulink url="https://tools.ietf.org/html/rfc7512">PKCS#11 URLs scheme</ulink>
|
|
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.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
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.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
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 <literal>softhsm</literal> which
|
|
provides a tool to setup a software HSM, and a PKCS#11 library.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
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 <literal>softhsm</literal> do not require this re-initialization
|
|
leading to applications working against software modules but failing with hardware
|
|
modules or smart cards. The wrapper PKCS#11 APIs provided by NSS, GNUTLS and
|
|
engine_pkcs11 (OpenSSL) handle the reinitialization after fork requirement transparently.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<section id="sect-Defensive_Coding-HSM-OpenSSL">
|
|
<title>OpenSSL HSM Support</title>
|
|
<para>
|
|
OpenSSL does not have native support for PKCS#11. It can
|
|
provide PKCS#11 support through the OpenSC's project
|
|
<literal>pkcs11</literal> engine (formerly known as <literal>engine_pkcs11</literal>).
|
|
As such software intended to use HSMs, must utilize that engine.
|
|
</para>
|
|
<para>
|
|
Engine <literal>pkcs11</literal> 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 <literal>p11-kit-proxy.so</literal>.
|
|
</para>
|
|
<para>
|
|
The following example demonstrates the initialization of the pkcs11 engine
|
|
and its usage to sign data.
|
|
</para>
|
|
<example id="ex-Defensive_Coding-HSM-OpenSSL">
|
|
<title>Signing data with HSM and OpenSSL</title>
|
|
<xi:include href="snippets/Features-HSM-OpenSSL.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude" />
|
|
</example>
|
|
|
|
</section>
|
|
<section id="sect-Defensive_Coding-HSM-GNUTLS">
|
|
<title>GNUTLS HSM Support</title>
|
|
<para>
|
|
GNUTLS supports PKCS#11 natively. Most of the API functions
|
|
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.
|
|
</para>
|
|
<para>
|
|
The following example demonstrates the initialization of the pkcs11 engine
|
|
and its usage to sign data.
|
|
</para>
|
|
<example id="ex-Defensive_Coding-HSM-GNUTLS">
|
|
<title>Signing data with HSM and GnuTLS</title>
|
|
<xi:include href="snippets/Features-HSM-GNUTLS.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude" />
|
|
</example>
|
|
<para>
|
|
The PIN callback function can be either set globally as in
|
|
the example above or locally by utilizing functions such as <literal>gnutls_privkey_set_pin_function</literal>.
|
|
An example PIN callback function is shown below.
|
|
</para>
|
|
<example id="ex-Defensive_Coding-HSM-GNUTLS-PIN">
|
|
<title>An example PIN callback with GNUTLS</title>
|
|
<xi:include href="snippets/Features-HSM-GNUTLS-PIN.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude" />
|
|
</example>
|
|
</section>
|
|
<section id="sect-Defensive_Coding-HSM-NSS">
|
|
<title>NSS HSM Support</title>
|
|
<para>
|
|
NSS supports PKCS#11 natively. In fact all NSS crypto operations,
|
|
including builtin 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.
|
|
</para>
|
|
<para>
|
|
The following example demonstrates a typical NSS application for signing.
|
|
</para>
|
|
<example id="ex-Defensive_Coding-HSM-NSS">
|
|
<title>Signing data with HSM and NSS</title>
|
|
<xi:include href="snippets/Features-HSM-NSS.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude" />
|
|
</example>
|
|
<para>
|
|
To use the example above with an HSM or smart card you will need to do the following.
|
|
</para>
|
|
<informalexample>
|
|
<programlisting language="Bash">
|
|
# 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}"
|
|
</programlisting>
|
|
</informalexample>
|
|
<example id="ex-Defensive_Coding-HSM-NSS-PIN">
|
|
<title>An example PIN callback with NSS</title>
|
|
<xi:include href="snippets/Features-HSM-NSS-PIN.xml"
|
|
xmlns:xi="http://www.w3.org/2001/XInclude" />
|
|
</example>
|
|
</section>
|
|
</chapter>
|