| |
@@ -0,0 +1,187 @@
|
| |
+ <?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>
|
| |
+ <important>
|
| |
+ <title>Possible conflict with SELinux</title>
|
| |
+ <para>
|
| |
+ The <literal>p11-kit-proxy.so</literal> module relies on code generation (function rewrite),
|
| |
+ and as such it may fail to operate in contexts where pages can be written but not executed.
|
| |
+ This is often the SELinux context under which servers like apache are executed.
|
| |
+ </para>
|
| |
+ </important>
|
| |
+ <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>
|
| |
This adds a section on using Hardware Security Modules and smart cards with applications using the OpenSSL, NSS and GnuTLS libraries.
The NSS parts were contributed by Robert Relyea.