defensive-coding-guide/_package/main/master/en-US/features/Features-HSM.html
Brian (bex) Exelbierd 2e8934be40 Converted to AsciiBinder
This required moving files around in the repository and shifting
from a master.adoc structure to _topic_map.yml, etc.

README and Makefile modified slightly to reflect new build process
2018-02-08 13:08:40 +01:00

617 lines
No EOL
36 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>Defensive Coding Guide | Defensive Coding Guide | Implementing Security Features | Hardware Security Modules and Smart Cards</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<!-- Overpass Font -->
<link rel="stylesheet" href="https://overpass-30e2.kxcdn.com/overpass.css">
<link href="../../../master/_stylesheets/asciibinder.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<link href="../../../master/_images/favicon32x32.png" rel="shortcut icon" type="text/css">
<!--[if IE]><link rel="shortcut icon" href="../../../master/_images/favicon.ico"><![endif]-->
<meta content="AsciiBinder" name="application-name">
</head>
<body>
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="https://docs.fedoraproject.org/"><img alt="Fedora Documentation" src="../../../master/_images/fedora.svg"></a>
</div>
</div>
</div>
<div class="container">
<p class="toggle-nav visible-xs pull-left">
<button class="btn btn-default btn-sm" type="button" data-toggle="offcanvas">Toggle nav</button>
</p>
<ol class="breadcrumb">
<li class="sitename">
<a href="../../../index.html">Home</a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide </a>
</li>
<li class="hidden-xs active">
<a href="../../en-US/index.html">Defensive Coding Guide</a>
</li>
<li class="hidden-xs active"><a href="../../en-US/features/Features-Authentication.html">Implementing Security Features</a></li>
<li class="hidden-xs active">
Hardware Security Modules and Smart Cards
</li>
</ol>
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 col-md-3 sidebar sidebar-offcanvas">
<ul class="nav nav-sidebar">
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicGroup0">
<span id="tgSpan0" class="fa fa-angle-down"></span>Defensive Coding Guide
</a>
<ul id="topicGroup0" class="collapse in list-unstyled">
<li><a class="" href="../../en-US/index.html">Book Information</a></li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-1">
<span id="sgSpan-0-1" class="fa fa-caret-right"></span>&nbsp;Programming Languages
</a>
<ul id="topicSubGroup-0-1" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/programming-languages/C.html">The C Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/CXX.html">The C++ Programming&nbsp;Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Java.html">The Java Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Python.html">The Python Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Shell.html">Shell Programming and bash</a></li>
<li><a class="" href="../../en-US/programming-languages/Go.html">The Go Programming Language</a></li>
<li><a class="" href="../../en-US/programming-languages/Vala.html">The Vala Programming Language</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-2">
<span id="sgSpan-0-2" class="fa fa-caret-right"></span>&nbsp;Specific Programming Tasks
</a>
<ul id="topicSubGroup-0-2" class="nav-tertiary list-unstyled collapse">
<li><a class="" href="../../en-US/tasks/Tasks-Library_Design.html">Library Design</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Descriptors.html">File Descriptor Management</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-File_System.html">File System Manipulation</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Temporary_Files.html">Temporary Files</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Processes.html">Processes</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Serialization.html">Serialization and Deserialization</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Cryptography.html">Cryptography</a></li>
<li><a class="" href="../../en-US/tasks/Tasks-Packaging.html">RPM Packaging</a></li>
</ul>
</li>
<li class="nav-header">
<a class="" href="#" data-toggle="collapse" data-target="#topicSubGroup-0-3">
<span id="sgSpan-0-3" class="fa fa-caret-down"></span>&nbsp;Implementing Security Features
</a>
<ul id="topicSubGroup-0-3" class="nav-tertiary list-unstyled collapse in">
<li><a class="" href="../../en-US/features/Features-Authentication.html">Authentication and Authorization</a></li>
<li><a class="" href="../../en-US/features/Features-TLS.html">Transport Layer Security (TLS)</a></li>
<li><a class=" active" href="../../en-US/features/Features-HSM.html">Hardware Security Modules and Smart Cards</a></li>
</ul>
</li>
<li><a class="" href="../../en-US/Revision_History.html">Revision History</a></li>
</ul>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-9 col-md-9 main">
<div class="page-header">
<h2>Hardware Security Modules and Smart Cards</h2>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>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 <code>opensc</code>
shared module (<code>opensc-pkcs11.so</code>) can be used for the majority
of smart cards available in the market. By convention these modules are located
at <code>/usr/lib64/pkcs11</code>. They can be used directly, or via
a higher level library.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>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 <a href="https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html">p11-kit
configuration files</a>, stored at <code>/etc/pkcs11/modules/</code>. For applications using
<code>engine_pkcs11</code> or GnuTLS the registered modules are
available without further configuration. Other applications will have to load
the <code>p11-kit-proxy.so</code> module.</p>
</li>
<li>
<p>Most crypto libraries support the <a href="https://tools.ietf.org/html/rfc7512">PKCS#11 URLs scheme</a>
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.</p>
</li>
<li>
<p>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.</p>
</li>
<li>
<p>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 <code>softhsm</code> which
provides a tool to setup a software HSM, and a PKCS#11 library.</p>
</li>
<li>
<p>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 <code>softhsm</code> 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.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-OpenSSL"><a class="anchor" href="#sect-Defensive_Coding-HSM-OpenSSL"></a>OpenSSL HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>OpenSSL does not have native support for PKCS#11. It can
provide PKCS#11 support through the OpenSC&#8217;s project
<code>pkcs11</code> engine (formerly known as <code>engine_pkcs11</code>).
As such software intended to use HSMs, must utilize that engine.</p>
</div>
<div class="paragraph">
<p>Engine <code>pkcs11</code> 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 <code>p11-kit-proxy.so</code>.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates the initialization of the pkcs11 engine
and its usage to sign data.</p>
</div>
<div id="ex-Defensive_Coding-HSM-OpenSSL" class="exampleblock">
<div class="title">Example 1. Signing data with HSM and OpenSSL</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c">OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
ERR_clear_error();
ENGINE_load_builtin_engines();
e = ENGINE_by_id(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">pkcs11</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (!e) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
<span style="color:#080;font-weight:bold">if</span> (module_path) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">loading: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, module_path);
<span style="color:#080;font-weight:bold">if</span> (!ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">MODULE_PATH</span><span style="color:#710">&quot;</span></span>, module_path, <span style="color:#00D">0</span>)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (!ENGINE_init(e)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
<span style="color:#080;font-weight:bold">if</span> (key_pass &amp;&amp; !ENGINE_ctrl_cmd_string(e, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">PIN</span><span style="color:#710">&quot;</span></span>, key_pass, <span style="color:#00D">0</span>)) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
private_key = ENGINE_load_private_key(e, private_key_name, <span style="color:#069">NULL</span>, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (!private_key) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">cannot load: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, private_key_name);
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
display_openssl_errors(__LINE__);
digest_algo = EVP_get_digestbyname(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">sha256</span><span style="color:#710">&quot;</span></span>);
EVP_MD_CTX_init(&amp;ctx);
<span style="color:#080;font-weight:bold">if</span> (EVP_DigestInit(&amp;ctx, digest_algo) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
EVP_SignInit(&amp;ctx, digest_algo);
<span style="color:#579">#define</span> TEST_DATA <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">test data</span><span style="color:#710">&quot;</span></span>
<span style="color:#080;font-weight:bold">if</span> (EVP_SignUpdate(&amp;ctx, TEST_DATA, <span style="color:#080;font-weight:bold">sizeof</span>(TEST_DATA) - <span style="color:#00D">1</span>) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
n = <span style="color:#080;font-weight:bold">sizeof</span>(buf);
<span style="color:#080;font-weight:bold">if</span> (EVP_SignFinal(&amp;ctx, buf, &amp;n, private_key) &lt;= <span style="color:#00D">0</span>) {
display_openssl_errors(__LINE__);
exit(<span style="color:#00D">1</span>);
}
EVP_PKEY_free(private_key);
ENGINE_finish(e);</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-GNUTLS"><a class="anchor" href="#sect-Defensive_Coding-HSM-GNUTLS"></a>GnuTLS HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates the initialization of the pkcs11 engine
and its usage to sign data.</p>
</div>
<div id="ex-Defensive_Coding-HSM-GNUTLS" class="exampleblock">
<div class="title">Example 2. Signing data with HSM and GnuTLS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#080;font-weight:bold">if</span> (module_path) {
ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_pkcs11_add_provider(module_path, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (key_pass)
gnutls_pkcs11_set_pin_function(pin_function, key_pass);
ret = gnutls_privkey_init(&amp;private_key);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_privkey_import_url(private_key, private_key_name, <span style="color:#00D">0</span>);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
ret = gnutls_privkey_sign_data(private_key, GNUTLS_DIG_SHA256, <span style="color:#00D">0</span>,
&amp;testdata, &amp;signature);
<span style="color:#080;font-weight:bold">if</span> (ret &lt; <span style="color:#00D">0</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">error in %d: %s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, __LINE__, gnutls_strerror(ret));
exit(<span style="color:#00D">1</span>);
}
gnutls_privkey_deinit(private_key);
gnutls_free(signature.data);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The PIN callback function can be either set globally as in
the example above or locally by utilizing functions such as <code>gnutls_privkey_set_pin_function</code>.
An example PIN callback function is shown below.</p>
</div>
<div id="ex-Defensive_Coding-HSM-GNUTLS-PIN" class="exampleblock">
<div class="title">Example 3. An example PIN callback with GNUTLS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">int</span> pin_function(<span style="color:#088;font-weight:bold">void</span> *userdata, <span style="color:#0a8;font-weight:bold">int</span> attempt, <span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *token_url,
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *token_label, <span style="color:#0a8;font-weight:bold">unsigned</span> flags, <span style="color:#0a8;font-weight:bold">char</span> *pin, size_t pin_max)
{
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_FINAL_TRY)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">This is the final try before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_COUNT_LOW)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Only few tries left before locking!</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (flags &amp; GNUTLS_PIN_WRONG)
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Wrong PIN has been provided in the previous attempt</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#777">/* userdata is the second value passed to gnutls_pkcs11_set_pin_function()
* in this example we passed the PIN as a null terminated value.
*/</span>
snprintf(pin, pin_max, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">%s</span><span style="color:#710">&quot;</span></span>, (<span style="color:#0a8;font-weight:bold">char</span>*)userdata);
<span style="color:#080;font-weight:bold">return</span> <span style="color:#00D">0</span>;
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="sect-Defensive_Coding-HSM-NSS"><a class="anchor" href="#sect-Defensive_Coding-HSM-NSS"></a>NSS HSM Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>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.</p>
</div>
<div class="paragraph">
<p>The following example demonstrates a typical NSS application for signing.</p>
</div>
<div id="ex-Defensive_Coding-HSM-NSS" class="exampleblock">
<div class="title">Example 4. Signing data with HSM and NSS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c">SECStatus rv;
CERTCertificate *cert = <span style="color:#069">NULL</span>;
SECKEYPrivateKey *pvtkey = <span style="color:#069">NULL</span>;
SECItem signature = { siBuffer, <span style="color:#069">NULL</span>, <span style="color:#00D">0</span> };
SECOidTag algTag;
<span style="color:#0a8;font-weight:bold">int</span> r = <span style="color:#00D">1</span>;
<span style="color:#0a8;font-weight:bold">unsigned</span> <span style="color:#0a8;font-weight:bold">char</span> buf[] = <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">test data to sign</span><span style="color:#710">&quot;</span></span>;
<span style="color:#088;font-weight:bold">const</span> <span style="color:#0a8;font-weight:bold">char</span> *cert_name;
<span style="color:#0a8;font-weight:bold">unsigned</span> i;
<span style="color:#080;font-weight:bold">if</span> (argc &lt; <span style="color:#00D">3</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">usage: %s [cert name] [PIN]</span><span style="color:#b0b">\n</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, argv[<span style="color:#00D">0</span>]);
exit(<span style="color:#00D">1</span>);
}
cert_name = argv[<span style="color:#00D">1</span>];
pin = argv[<span style="color:#00D">2</span>];
PK11_SetPasswordFunc(passwdcb);
NSS_InitializePRErrorTable();
rv = NSS_Init(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">.</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (rv != SECSuccess) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">NSS initialization failed (err %d)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, PR_GetError());
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
cert = PK11_FindCertFromNickname(cert_name, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (cert == <span style="color:#069">NULL</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Couldn't find cert %s in NSS db (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Buffer being signed = </span><span style="color:#b0b">\n</span><span style="color:#D20">%s</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>, buf);
pvtkey = PK11_FindKeyByAnyCert(cert, <span style="color:#069">NULL</span>);
<span style="color:#080;font-weight:bold">if</span> (pvtkey == <span style="color:#069">NULL</span>) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Couldn't find private key for cert %s (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}
<span style="color:#777">/* get the algtag. Pick the default hash algorithm */</span>
algTag = SEC_GetSignatureAlgorithmOidTag(pvtkey-&gt;keyType, SEC_OID_UNKNOWN);
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Signing with alg = %s (%d)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
SECOID_FindOIDTagDescription(algTag), algTag);
rv = SEC_SignData(&amp;signature, buf, <span style="color:#080;font-weight:bold">sizeof</span>(buf)-<span style="color:#00D">1</span>, pvtkey, algTag);
<span style="color:#080;font-weight:bold">if</span> (rv != SECSuccess) {
fprintf(stderr, <span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">sign with Private Key failed (err %d: %s)</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>,
PR_GetError(), PORT_ErrorToString(PR_GetError()));
<span style="color:#080;font-weight:bold">goto</span> cleanup;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>To use the example above with an HSM or smart card you will need to do the following.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="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 &quot;My HSM&quot; -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 &quot;${token_name}:${cert_name}&quot;</code></pre>
</div>
</div>
<div id="ex-Defensive_Coding-HSM-NSS-PIN" class="exampleblock">
<div class="title">Example 5. An example PIN callback with NSS</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="c"><span style="color:#0a8;font-weight:bold">char</span> *passwdcb(PK11SlotInfo * slot, PRBool retry, <span style="color:#088;font-weight:bold">void</span> *arg)
{
<span style="color:#080;font-weight:bold">if</span> (!isatty(STDIN_FILENO) &amp;&amp; retry) {
<span style="color:#777">/* we're just reading from a file, and the value is known to be wrong,
* don't keep bounding the token with the wrong password. */</span>
<span style="color:#080;font-weight:bold">return</span> <span style="color:#069">NULL</span>;
}
<span style="color:#080;font-weight:bold">if</span> (retry) {
printf(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20">Warning: Wrong PIN has been provided in the previous attempt</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
<span style="color:#080;font-weight:bold">if</span> (PK11_IsHW(slot)) {
printf
(<span style="background-color:hsla(0,100%,50%,0.05)"><span style="color:#710">&quot;</span><span style="color:#D20"> NOTE: multiple pin failures could result in locking your device</span><span style="color:#b0b">\n</span><span style="color:#710">&quot;</span></span>);
}
}
<span style="color:#080;font-weight:bold">if</span> (pin == <span style="color:#069">NULL</span>)
<span style="color:#080;font-weight:bold">return</span> pin;
<span style="color:#080;font-weight:bold">else</span>
<span style="color:#080;font-weight:bold">return</span> strdup(pin);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="bottom" class="text-muted py-3" >
<div class="foot">
<div class="container">
<div class="row footerlinks">
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">About</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Overview">About Fedora</a></dd>
<dd><a href="https://getfedora.org/en/sponsors">Sponsors</a></dd>
<dd><a href="https://fedoramagazine.org">Fedora Magazine</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Legal:Main#Legal">Legal</a></dd>
</dl>
<ul class="list-inline">
<li>
<a href="https://www.facebook.com/TheFedoraProject" class="btn-social btn-outline"><i class="fa fa-fw fa-facebook"></i></a>
</li>
<li>
<a href="https://plus.google.com/112917221531140868607" class="btn-social btn-outline"><i class="fa fa-fw fa-google-plus"></i></a>
</li>
<li>
<a href="https://twitter.com/fedora" class="btn-social btn-outline"><i class="fa fa-fw fa-twitter"></i></a>
</li>
</ul>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title uppercase">Download</h3>
<div class="widget-body">
<dl>
<dd><a href="https://getfedora.org/en/workstation/download">Get Fedora Workstation</a></dd>
<dd><a href="https://getfedora.org/en/server/download">Get Fedora Server</a></dd>
<dd><a href="https://getfedora.org/en/atomic/download">Get Fedora Atomic</a></dd>
<dd><a href="https://spins.fedoraproject.org">Fedora Spins</a></dd>
<dd><a href="https://labs.fedoraproject.org">Fedora Labs</a></dd>
<dd><a href="https://arm.fedoraproject.org">Fedora ARM<span class="sup">&reg;</span></a></dd>
<dd><a href="https://alt.fedoraproject.org/">Alternative Downloads</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Support</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Communicating_and_getting_help">Get Help</a></dd>
<dd><a href="https://ask.fedoraproject.org/">Ask Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/Common_F27_bugs">Common Bugs</a></dd>
<dd><a href="https://developer.fedoraproject.org/">Fedora Developer Portal</a></dd>
<dd><a href="https://docs.fedoraproject.org/f27/install-guide/index.html">Installation Guide</a></dd>
</dl>
</div>
</div>
<div class="col-sm-3 col-xs-6 widget">
<h3 class="widget-title">Join</h3>
<div class="widget-body">
<dl>
<dd><a href="https://fedoraproject.org/wiki/Join">Join Fedora</a></dd>
<dd><a href="http://fedoraplanet.org">Planet Fedora</a></dd>
<dd><a href="https://fedoraproject.org/wiki/SIGs">Fedora SIGs</a></dd>
<dd><a href="https://admin.fedoraproject.org/accounts/">Fedora Account System</a></dd>
<dd><a href="https://fedoracommunity.org/">Fedora Community</a></dd>
</dl>
</div>
</div>
</div> <!-- /row of widgets -->
<div class="row">
<div class="col-md-2">
<div class="widget-body">
<a href="https://www.redhat.com/"><img class="rh-logo" src="../../../master/_images/redhat-logo.png" alt="Red Hat Logo" /></a>
</div>
</div>
<div class="col-md-7">
<div class="widget-body">
<p class="sponsor">Fedora is sponsored by Red Hat.</p>
<p class="sponsor"><a href="https://www.redhat.com/en/technologies/linux-platforms/articles/relationship-between-fedora-and-rhel">Learn more about the relationship between Red Hat and Fedora &raquo;</a></p>
<p class="copy">&copy; 2017 Red Hat, Inc. and others. Please send any comments or corrections to the <a href="https://pagure.io/fedora-docs/docs-fp-o">documentation team</a></p>
</div>
</div>
</div> <!-- /row of widgets -->
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="../../../master/_javascripts/bootstrap-offcanvas.js" type="text/javascript"></script>
<script type="text/javascript">
/*<![CDATA[*/
$(document).ready(function() {
$("[id^='topicGroup']").on('show.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicGroup']").on('hide.bs.collapse', function (event) {
if (!($(event.target).attr('id').match(/^topicSubGroup/))) {
$(this).parent().find("[id^='tgSpan']").toggleClass("fa-angle-right fa-angle-down");
}
});
$("[id^='topicSubGroup']").on('show.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
$("[id^='topicSubGroup']").on('hide.bs.collapse', function () {
$(this).parent().find("[id^='sgSpan']").toggleClass("fa-caret-right fa-caret-down");
});
});
/*]]>*/
</script>
</body>
</html>