<?xml version="1.0" encoding="UTF-8"?>
<rss version='2.0' xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Dennis Verslegers</title>
    <description>... Regularly reinventing a slightly different wheel ...</description>
    <link>https://dennis.silvrback.com/feed</link>
    <atom:link href="https://dennis.silvrback.com/feed" rel="self" type="application/rss+xml"/>
    <category domain="dennis.silvrback.com">Content Management/Blog</category>
    <language>en-us</language>
      <pubDate>Thu, 10 Jul 2014 15:35:03 +0100</pubDate>
    <managingEditor>dennis.verslegers@sd-consult.be (Dennis Verslegers)</managingEditor>
      <item>
        <guid>https://dennis.silvrback.com/openssl-web-front-end#5847</guid>
          <pubDate>Thu, 10 Jul 2014 15:35:03 +0100</pubDate>
        <link>https://dennis.silvrback.com/openssl-web-front-end</link>
        <title>OpenSSL web front-end</title>
        <description>written in python, based on twitter bootstrap</description>
        <content:encoded><![CDATA[<p>Recently I&#39;ve been working on some projects related to OpenSSL and Certification Authorities. The challenge is not related to the use of OpenSSL, which can be mastered by memorising a limited set of commands, but rather lies in the consequent use of these commands, maintaining the proper naming conventions, directory structure and options / settings. To make the use of a OpenSSL based CA a bit more accessible I decided to write a &#39;small&#39; python web front-end.</p>

<p>The tool itself will perform the commands on the host system through normal openssl command lines and therefore maintains full compatibility with OpenSSL itself. If something goes wrong or you need something done manually you can still issue the proper commands.</p>

<p>The pyPKI front-end has the following features and capabilities:<br>
* Request new client or server certificate<br>
* Perform bulk requests based on csv import file<br>
* Revoke certificates<br>
* Generate Certificate Revocation Lists<br>
* Create reports on certificate expiration<br>
* Reads most configuration settings from openssl.cnf such as Certification Authorities, default CSR parameters and more. See <a href="https://dennis.silvrback.com/establish-multi-level-public-key-infrastructure-using-openssl">this blog post</a> for instructions how to implement the basic filesystem structure for use with pyPKI<br>
* Supports the use of Yubikey Neo with PIV applet to store the CA private key(s). See <a href="https://dennis.silvrback.com/openssl-ca-with-yubikey-neo">this blog post</a> for instructions how to implement the Yubikey Neo to store your private keys.</p>

<p>You can download the pyPKI application <a href="https://bitbucket.org/dverslegers/pypki">here</a>. Or by issuing:</p>
<div class="highlight"><pre><span></span><span class="n">git</span> <span class="n">clone</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">dverslegers</span><span class="nd">@bitbucket.org</span><span class="o">/</span><span class="n">dverslegers</span><span class="o">/</span><span class="n">pypki</span><span class="o">.</span><span class="n">git</span>
</pre></div>
<p>The installation instructions can be found in the readme.pdf located in the root directory.</p>

<p>Some screenshots of the application:</p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/5946e150-f212-44cf-8a68-e976909b5f49/Screen%20Shot%202014-07-10%20at%2016.07.09_large.png" /></p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/39603f0b-1b29-4d23-9f02-d828863d2d39/Screen%20Shot%202014-07-10%20at%2016.07.23_large.png" /></p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/641d709b-c429-4841-a708-09bb34387631/Screen%20Shot%202014-07-10%20at%2016.07.34_large.png" /></p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/66cc69df-eb09-4821-adbe-2570bfb7536e/Screen%20Shot%202014-07-10%20at%2016.08.04_large.png" /></p>
]]></content:encoded>
      </item>
      <item>
        <guid>https://dennis.silvrback.com/establish-multi-level-public-key-infrastructure-using-openssl#5846</guid>
          <pubDate>Thu, 10 Jul 2014 15:06:16 +0100</pubDate>
        <link>https://dennis.silvrback.com/establish-multi-level-public-key-infrastructure-using-openssl</link>
        <title>Establish multi-level Public Key Infrastructure using OpenSSL</title>
        <description></description>
        <content:encoded><![CDATA[<h2 id="objectives">Objectives</h2>

<p>In this short how-to guide we will establish a Public Key Infrastructure based on OpenSSL. To keep things simple and straight forward we only define two levels (although many more are possible):<br>
- A Root Certification Authority which is only used to sign certificates of subordinate intermediary Certification Authorities<br>
- An Intermediary Certificate Authority which is used to issue certificates for both servers and users</p>

<p>It should however be easy to modify the instructions below to your target implementation.</p>

<h2 id="creating-a-dedicated-user-for-pki-operations">Creating a dedicated user for pki operations</h2>

<p>For security reasons it is preferable to create a dedicated user for use with your PKI and to ensure that only this user (or group of users) has access to this location. In our setup we will create a user called <strong>pki</strong> and use the homedirectory for this account as root for the PKI.</p>
<div class="highlight"><pre><span></span>sudo adduser pki
chmod -R 0700 /home/pki/pki-root
</pre></div>
<p>Make sure you repeat the last command when the PKI setup is completed to ensure that no files or directories remain <em>world</em> readable.</p>

<h2 id="a-word-about-structure">A word about structure</h2>

<p>The following directory structure is recommended as a skeleton for setting up a new PKI. Each Certificate Authority in your Public Key Infrastructure should have a directory structure similar to the one explained below.</p>

<p><strong>PKI directory</strong>: Root directory for the OpenSSL PKI<br>
<strong>CA directory</strong> : Root directory for the Certificate Authority<br>
<strong>CA.db.tmp</strong>: Temporary directory for openssl operations. This directory will mainly be used to store intermediary .pem files.<br>
<strong>CA.db.certs</strong>: Directory used to store generated certificates in .pem format. It is advised to create additional subdirectories corresponding to the common name of the generated certificate to hold certificates, private keys and other formats such as p12 containers for future reference.<br>
<strong>CA.db.crl</strong>: Directory used to store certificate revocation lists generated by openssl.</p>

<p>Additionally the following files will need to be created for the CA to function properly.</p>

<p><strong>CA.db.serial</strong>: File indicating serial to be used for the next generated certificate. The initial value should be 01.<br>
<strong>CA.db.crlserial</strong>: File indicating serial to be used for the next CRL. The initial value should be 01.<br>
<strong>CA.db.index</strong>: Text based database file used by OpenSSL to store details of all generated certificates. Initially this file should be empty.<br>
<strong>CA.db.rand</strong>: File containing a random string which ensures the randomness of the CA. If security is of high importance it is recommended to use a hardware random key generator for this.</p>

<p>To simplify our setup we will consistently use the following naming and extension convention throughout our PKI:<br>
<strong>.crt</strong>: File containing a certificate<br>
<strong>.csr</strong>: File containing a Certificate Signing Request<br>
<strong>.key</strong>: File containing a private key<br>
<strong>.p12</strong>: Binary container with certificate, private key and ca chain<br>
<strong>.pwd</strong>: File containing the password used to open the p12 container</p>

<p>The commands to put the above mentioned structure in place are mentioned below. Make sure you modify <em>ca</em> in the example to reflect the name of the CA you are putting in place and make sure you execute the commands within the proper location on the filesystem (in this example /home/pki/pki-root).</p>
<div class="highlight"><pre><span></span>mkdir ca
mkdir ca/ca.db.tmp
mkdir ca/ca.db.certs
mkdir ca/ca.db.crl
echo 01 &gt; ca/ca.db.serial
echo 01 &gt; ca/ca.db.crlserial
touch ca/ca.db.index
openssl rand -out ca/ca.db.rand 8192
</pre></div>
<h2 id="configure-openssl-through-openssl-cnf">Configure OpenSSL through openssl.cnf</h2>

<p>The OpenSSL configuration file allows us to (pre-)define many of the settings related to our Certificate authority. Although many of these options can equally be set using command line parameters we can simplify our command lines and standardise the creation of certificates by using the configuration file.</p>

<p>We will define the following aspects of our Certification Authority through the configuration file:<br>
- The Certification Authorities making up our Public Key Infrastructure and their related settings such as base directories and files.<br>
- The policies to be applied to certificate requests, indicating which fields are optional, mandatory and/or should match the Certification Authorities values.<br>
- The standard certificate request parameters to be used.<br>
- The extensions to be used when generating specific types of certificates.</p>

<p>Let us create the OpenSSL file and place it in our root PKI directory (/home/pki/). The OpenSSL configuration file should start with a entry indicating which Certification Authority should be used by default is none is specified during certificate generation.</p>
<div class="highlight"><pre><span></span><span class="k">[ ca ]</span>
<span class="na">default_ca</span>  <span class="o">=</span> <span class="s">CA        # The default ca section</span>
</pre></div>
<p>As a next step we need to introduce a CA configuration section for each of the CA’s which make up our Public Key Infrastructure. </p>

<blockquote>
<p>Note: if your PKI only consists of one CA you should only create one section.<br>
Note: Make sure to replace CA with the name of the Certification Authority you are implementing, in our example RootCA and IntermCA.</p>
</blockquote>
<div class="highlight"><pre><span></span><span class="k">[ CA ]</span>

<span class="na">dir</span>     <span class="o">=</span> <span class="s">./CA            </span>
<span class="c1"># Where everything is kept</span>
<span class="na">certs</span>       <span class="o">=</span> <span class="s">$dir/ca.db.certs      </span>
<span class="c1"># Where the issued certs are kept</span>
<span class="na">crl_dir</span> <span class="o">=</span> <span class="s">$dir/ca.db.crl         </span>
<span class="c1"># Where the issued crl are kept</span>
<span class="na">database</span>    <span class="o">=</span> <span class="s">$dir/ca.db.index     </span>
<span class="c1"># database index file.</span>
<span class="na">unique_subject</span> <span class="o">=</span> <span class="s">no           </span>
<span class="c1"># Set to &#39;no&#39; to allow creation of several ctificates with same subject.</span>
<span class="na">new_certs_dir</span>   <span class="o">=</span> <span class="s">$dir/ca.db.certs </span>
<span class="c1"># default place for new certs.</span>
<span class="na">certificate</span> <span class="o">=</span> <span class="s">$dir/ca.crt   </span>
<span class="c1"># The CA certificate</span>
<span class="na">serial</span>      <span class="o">=</span> <span class="s">$dir/ca.db.serial     </span>
<span class="c1"># The current serial number</span>
<span class="na">crlnumber</span>   <span class="o">=</span> <span class="s">$dir/ca.db.crlserial  </span>
<span class="c1"># the current crl number must be commented out to leave a V1 CRL</span>
<span class="na">private_key</span> <span class="o">=</span> <span class="s">$dir/ca.key             </span>
<span class="c1"># The private key</span>
<span class="na">RANDFILE</span>    <span class="o">=</span> <span class="s">$dir/ca.db.rand        </span>
<span class="c1"># private random number file</span>
<span class="na">name_opt</span>    <span class="o">=</span> <span class="s">ca_default        </span>
<span class="c1"># Subject Name options</span>
<span class="na">cert_opt</span>    <span class="o">=</span> <span class="s">ca_default        </span>
<span class="c1"># Certificate field options</span>

<span class="na">default_days</span>    <span class="o">=</span> <span class="s">365           </span>
<span class="c1"># how long to certify for</span>
<span class="na">default_crl_days</span>  <span class="o">=</span> <span class="s">60          </span>
<span class="c1"># how long before next CRL</span>
<span class="na">default_md</span>  <span class="o">=</span> <span class="s">md5       </span>
<span class="c1"># use public key default MD</span>
<span class="na">preserve</span>    <span class="o">=</span> <span class="s">no            </span>
<span class="c1"># keep passed DN ordering</span>

<span class="na">policy</span>          <span class="o">=</span> <span class="s">policy_match</span>
</pre></div>
<blockquote>
<p>The options, policy match and unique subject are most commonly used for root certification authorities since you will want the attributes of the intermediary CA’s to match the root CA and to ensure that you have a unique subject.  These two options should potentially be modified for intermediary CA’s.</p>
</blockquote>

<p>Make sure to modify the relevant values to reflect the configuration of the CA’s you want to put in place. Additionally it is advisable to modify the default_ca parameter to contain the CA you want to use for signing certificates by default.</p>

<p>Once we defined the CA’s we have the option of creating a policy which will be applied to certificate signing requests. By default the OpenSSL configuration file contains two policies called policy_match and policy_anything. <br>
The first requires the request to match most of the values present in the CA certificate such as country name, state or province etc.<br>
The latter imposes no restrictions on the content of the certificate signing request.</p>
<div class="highlight"><pre><span></span><span class="k">[ policy_match ]</span>
<span class="na">countryName</span>     <span class="o">=</span> <span class="s">match</span>
<span class="na">stateOrProvinceName</span> <span class="o">=</span> <span class="s">match</span>
<span class="na">localityName</span>            <span class="o">=</span> <span class="s">optional </span>
<span class="na">organizationName</span>    <span class="o">=</span> <span class="s">optional</span>
<span class="na">organizationalUnitName</span>  <span class="o">=</span> <span class="s">optional</span>
<span class="na">commonName</span>      <span class="o">=</span> <span class="s">supplied</span>
<span class="na">emailAddress</span>        <span class="o">=</span> <span class="s">optional</span>

<span class="k">[ policy_anything ]</span>
<span class="na">countryName</span>     <span class="o">=</span> <span class="s">optional</span>
<span class="na">stateOrProvinceName</span> <span class="o">=</span> <span class="s">optional</span>
<span class="na">localityName</span>        <span class="o">=</span> <span class="s">optional</span>
<span class="na">organizationName</span>    <span class="o">=</span> <span class="s">optional</span>
<span class="na">organizationalUnitName</span>  <span class="o">=</span> <span class="s">optional</span>
<span class="na">commonName</span>      <span class="o">=</span> <span class="s">supplied</span>
<span class="na">emailAddress</span>        <span class="o">=</span> <span class="s">optional</span>
</pre></div>
<p>Let’s go ahead and define our own policy which is to be used when signing user certificates. Feel free to modify the template below to match whatever requirements you want to put on specific types of certificate signing requests.</p>
<div class="highlight"><pre><span></span><span class="k">[ policy_usr ]</span>
<span class="na">countryName</span>     <span class="o">=</span> <span class="s">supplied</span>
<span class="na">stateOrProvinceName</span> <span class="o">=</span> <span class="s">supplied</span>
<span class="na">localityName</span>        <span class="o">=</span> <span class="s">supplied</span>
<span class="na">organizationName</span>    <span class="o">=</span> <span class="s">supplied</span>
<span class="na">organizationalUnitName</span>  <span class="o">=</span> <span class="s">optional</span>
<span class="na">commonName</span>      <span class="o">=</span> <span class="s">supplied</span>
<span class="na">emailAddress</span>        <span class="o">=</span> <span class="s">supplied</span>
</pre></div>
<p>With our CA’s and policies in place it’s time to define the ‘default’ request parameters. Modify the parameters below to reflect your organisation</p>
<div class="highlight"><pre><span></span><span class="k">[ req ]</span>
<span class="na">default_bits</span>        <span class="o">=</span> <span class="s">2048</span>
<span class="na">default_keyfile</span>     <span class="o">=</span> <span class="s">privkey.pem</span>
<span class="na">distinguished_name</span>  <span class="o">=</span> <span class="s">req_distinguished_name</span>
<span class="na">attributes</span>      <span class="o">=</span> <span class="s">req_attributes</span>
<span class="na">x509_extensions</span> <span class="o">=</span> <span class="s">v3_ca # The extentions to add to the self signed cert</span>
<span class="na">string_mask</span> <span class="o">=</span> <span class="s">nombstr</span>

<span class="k">[ req_distinguished_name ]</span>
<span class="na">countryName</span>         <span class="o">=</span> <span class="s">Country Name (2 letter code)</span>
<span class="na">countryName_default</span>     <span class="o">=</span> <span class="s">BE</span>
<span class="na">countryName_min</span>         <span class="o">=</span> <span class="s">2</span>
<span class="na">countryName_max</span>         <span class="o">=</span> <span class="s">2</span>

<span class="na">stateOrProvinceName</span>     <span class="o">=</span> <span class="s">State or Province Name (full name)</span>
<span class="na">stateOrProvinceName_default</span> <span class="o">=</span> <span class="s">Vlaams-Brabant</span>

<span class="na">localityName</span>            <span class="o">=</span> <span class="s">Locality Name (eg, city)</span>
<span class="na">localityName_default</span>        <span class="o">=</span> <span class="s">Leuven</span>

<span class="na">0.organizationName</span>      <span class="o">=</span> <span class="s">Organization Name (eg, company)</span>
<span class="na">0.organizationName_default</span>  <span class="o">=</span> <span class="s">AUSY</span>

<span class="na">1.organizationName</span>      <span class="o">=</span> <span class="s">Second Organization Name (eg, company)</span>
<span class="na">1.organizationName_default</span>  <span class="o">=</span> <span class="s">not used</span>

<span class="na">organizationalUnitName</span>      <span class="o">=</span> <span class="s">Organizational Unit Name (eg, section)</span>
<span class="na">organizationalUnitName_default</span>  <span class="o">=</span> <span class="s">Demo CA project</span>

<span class="na">commonName</span>          <span class="o">=</span> <span class="s">Common Name (eg, YOUR name)</span>
<span class="na">commonName_max</span>          <span class="o">=</span> <span class="s">64</span>

<span class="na">emailAddress</span>            <span class="o">=</span> <span class="s">Email Address</span>
<span class="na">emailAddress_max</span>        <span class="o">=</span> <span class="s">64</span>

<span class="k">[ req_attributes ]</span>
<span class="c1"># challengePassword     = A challenge password</span>
<span class="c1"># challengePassword_min     = 4</span>
<span class="c1"># challengePassword_max     = 20</span>

<span class="c1"># unstructuredName      = An optional company name</span>
</pre></div>
<p>As a final step we have the option of defining specific extensions, contstraints and comments for specific certificate types. Below you find an example of  server and user certificate types and their specifics. Make sure to modify the crlDistributionPoints and/or comment to reflect your environment.</p>
<div class="highlight"><pre><span></span><span class="k">[ srv_cert ]</span>
<span class="na">basicConstraints</span><span class="o">=</span><span class="s">CA:FALSE</span>
<span class="na">nsCertType</span>            <span class="o">=</span> <span class="s">server</span>
<span class="na">crlDistributionPoints</span> <span class="o">=</span> <span class="s">URI:http://example.com/crl.pem</span>
<span class="na">nsComment</span>           <span class="o">=</span> <span class="s">&quot;OpenSSL Generated Server Certificate&quot;</span>

<span class="k">[ usr_cert ]</span>
<span class="na">basicConstraints</span><span class="o">=</span><span class="s">CA:FALSE</span>
<span class="na">nsCertType</span> <span class="o">=</span> <span class="s">client, email</span>
<span class="na">nsComment</span>           <span class="o">=</span> <span class="s">&quot;OpenSSL Generated Client Certificate&quot;</span>
<span class="na">subjectKeyIdentifier</span><span class="o">=</span><span class="s">hash</span>
<span class="na">authorityKeyIdentifier</span><span class="o">=</span><span class="s">keyid,issuer:always</span>
</pre></div>
<p>The v3req, v3ca and crlext definitions are required for OpenSSL to function properly. These sections define the basic configuration for a common certificate request and the required extensions to generate a CA certificate. The crlext section defines how CRL’s are generated.</p>
<div class="highlight"><pre><span></span><span class="k">[ v3_req ]</span>
<span class="na">basicConstraints</span> <span class="o">=</span> <span class="s">CA:FALSE</span>
<span class="na">keyUsage</span> <span class="o">=</span> <span class="s">nonRepudiation, digitalSignature, keyEncipherment</span>

<span class="k">[ v3_ca ]</span>
<span class="c1"># Extensions for a typical CA</span>
<span class="na">subjectKeyIdentifier</span><span class="o">=</span><span class="s">hash</span>
<span class="na">authorityKeyIdentifier</span><span class="o">=</span><span class="s">keyid:always,issuer:always</span>
<span class="na">basicConstraints</span> <span class="o">=</span> <span class="s">CA:true</span>

<span class="k">[ crl_ext ]</span>
<span class="c1"># CRL extensions.</span>
<span class="na">authorityKeyIdentifier</span><span class="o">=</span><span class="s">keyid:always,issuer:always</span>

<span class="c1">## Establishing our CA’s</span>
<span class="c1">### Setup Root CA</span>
</pre></div>
<p>Create Root CA public / private keypair<br>
<code><br>
openssl genrsa -des3 -out ./RootCA/RootCA.key 2048<br>
</code><br>
Generate Root CA certificate, which is by definition a self signed certificate. Don’t forget to modify the validity to an appropriate value.<br>
<code><br>
openssl req -new -x509 -days 3650 -key ./RootCA/RootCA.key -out ./RootCA/RootCA.crt -config openssl.cnf<br>
</code></p>

<h3 id="setup-intermediary-ca-s">Setup intermediary CA(’s)</h3>

<p>Create Intermediate CA public / private keypair<br>
<code><br>
mkdir ./RootCA/RootCA.db.certs/IntermCA<br>
openssl genrsa -des3 -out ./RootCA/RootCA.db.certs/IntermCA/IntermCA.key 2048<br>
</code></p>

<p>Generate Certificate Siging Request for intermediary CA. Don’t forget to modify the validity to an appropriate value.<br>
<code><br>
openssl req -new -days 1095 -key ./RootCA/RootCA.db.certs/IntermCA/IntermCA.key -out ./RootCA/RootCA.db.certs/IntermCA/IntermCA.csr -config openssl.cnf<br>
</code><br>
Sign the previously generated CSR using the RootCA while adding the CA extension to ensure that the resulting certificate can be used to sign other certificates.<br>
<code><br>
openssl ca -config openssl.cnf -name RootCA -extensions v3_ca -out ./RootCA/RootCA.db.certs/IntermCA/IntermCA.crt -infiles ./RootCA/RootCA.db.certs/IntermCA/IntermCA.csr<br>
</code><br>
Now copy over the relevant certificate and key to the IntermCA root.<br>
<code><br>
cp ./RootCA/RootCA.db.certs/IntermCA/IntermCA.crt ./RootCA/RootCA.db.certs/IntermCA/IntermCA.key ./IntermCA/<br>
</code></p>

<p>It’s recommended to create a certificate chain file for future use. This file can be imported by a client and will indicate the full chain of Certification Authorities linked to the provided certificate.</p>

<h2 id="common-operations">Common operations</h2>

<p>That’s it, all relevant bits and pieces should be in place to start using our OpenSSL PKI. In this section you will find some common operations and the related openssl commands.</p>

<p>Generate server certificate<br>
<code><br>
openssl req -newkey rsa:2048 -keyout ./IntermCA/IntermCA.db.certs/server.domain/server.domain.key -nodes -config openssl.cnf -out ./IntermCA/IntermCA.db.certs/server.domain/server.domain.csr<br>
openssl ca -config openssl.cnf -name IntermCA -out ./IntermCA/IntermCA.db.certs/server.domain/server.domain.crt -infiles ./IntermCA/IntermCA.db.certs/server.domain/server.domain.csr<br>
</code></p>

<p>Generate user certificate<br>
<code><br>
openssl req -newkey rsa:2048 -keyout ./IntermCA/IntermCA.db.certs/username/username.key -nodes -config openssl.cnf -out ./IntermCA/IntermCA.db.certs/username/username.csr<br>
&#39;&#39; openssl ca -config openssl.cnf -extensions usr_cert -name IntermCA -out ./IntermCA/IntermCA.db.certs/username/username.crt -infiles ./IntermCA/IntermCA.db.certs/username/username.csr<br>
</code></p>

<p>Generate p12<br>
<code><br>
openssl pkcs12 -export -clcerts -in ./IntermCA/IntermCA.db.certs/server.domain/server.domain.crt -inkey ./IntermCA/IntermCA.db.certs/server.domain/server.domain.key -certfile ./pki.crt -out ./IntermCA/IntermCA.db.certs/server.domain/server.domain.p12<br>
</code></p>

<p>Revoke certificate<br>
<code><br>
openssl ca -config openssl.cnf -name IntermCA -revoke ./IntermCA/IntermCA.db.certs/02.pem<br>
</code></p>

<p>Generate CRL<br>
<code><br>
openssl ca -config openssl.cnf -name IntermCA -gencrl -out ./IntermCA/IntermCA.crl/crl-27.02.2014.pem<br>
</code></p>

<p>Generate CA chain<br>
<code><br>
cat ./RootCA/RootCA.crt ./IntermCA/IntermCA.crt &gt; pki.crt<br>
</code></p>
]]></content:encoded>
      </item>
      <item>
        <guid>https://dennis.silvrback.com/openssl-ca-with-yubikey-neo#3248</guid>
          <pubDate>Mon, 28 Apr 2014 14:59:57 +0100</pubDate>
        <link>https://dennis.silvrback.com/openssl-ca-with-yubikey-neo</link>
        <title>OpenSSL CA with Yubikey Neo</title>
        <description>My notes to setup an OpenSSL Certificate Authority with CA private key stored on the Yubikey Neo with PIV applet</description>
        <content:encoded><![CDATA[<p>I&#39;m currently looking for a way to use the Yubikey Neo as a smart card to store the private key of a Certificate Authority which can then subsequently be used to sign certificate requests. The CA is based on OpenSSL and therefore the Neo should integrate with OpenSSL as neatly as possible.</p>

<p>All the information you find here is already out there on the web, I just decided to put everything together in this post to avoid searching for bits and pieces of the solution.</p>

<h2 id="assumptions">Assumptions</h2>

<ul>
<li><p>You already have an OpenSSL based certification authority in place for which you have previously generated a certificate and key pair. The CA&#39;s certificate and key pair is available in the form of a p12 container. Alternatively you could also choose the route of generating the private key directly on the Neo and then creating the CA certificate form there. Although this is a &#39;more secure&#39; approach from security point of view it&#39;s not recommendable for this specific use case since you might want to recover or duplicate your private key in case the Yubikey Neo dies on you. This is only possible if you generate the private key outside of the Yubikey and then import it later on.</p></li>
<li><p>You have a Yubikey Neo with the PIV applet preloaded at your disposal</p></li>
</ul>

<h2 id="configuring-yubikey-neo-for-smart-card-ccid-interface-support">Configuring Yubikey Neo for smart card (CCID) interface support</h2>

<p>Recently yubico released a gui application called neo-manager allowing you to configure the neo. The current version (0.1.0) can be downloaded from <a href="http://opensource.yubico.com/yubikey-neo-manager/releases.html">here </a>.</p>

<p>For common use it is recommended to configure the Yubikey Neo to use the HID + CCID with touch eject mode. This allows the Neo to act as a smart card (CCID) and OTP simultaneously. It does so by acting as a smart card whenever it is connected to a system, unless the button is pushed. In this case it will eject the smartcard, act as a regular yubikey OTP and after that insert the smartcard again.</p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/ddc42af7-7ecf-44e5-a5a1-3f8bcaa2ce53/Screen%20Shot%202014-04-25%20at%2012.01.46_medium.png" /></p>

<p>For our specific purpose we could configure Neo to act only as a smart card (CCID) because we don&#39;t want to use our yubikey for anything other then (securely) storing the Certification Authority private key.</p>

<p><img alt="Silvrback blog image" src="https://silvrback.s3.amazonaws.com/uploads/8c798596-49b9-4a9b-a2e6-6edd37db6ccd/Screen%20Shot%202014-04-25%20at%2012.07.27_medium.png" /></p>

<h2 id="getting-our-system-to-see-neo-as-a-smartcard">Getting our system to see neo as a smartcard</h2>

<p>With the yubikey neo configured to act as a CCID device we need to get our system to interface with it. In my setup I will be using an Ubuntu Server 14.04 64bit system running inside of a VMWare Fusion virtual machine (USB 2.0 compatibility) for testing purposes, the steps required to get this to work on other Linux or OS X systems should be fairly similar.</p>

<p>We start by installing the opensc package on our system which contains the tools and drivers we need to get our yubikey piv up and running.</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ apt-get install opensc
</pre></div>
<p>Now let&#39;s test if we can access our yubikey neo using opensc:</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ opensc-tool -l
<span class="c1"># Detected readers (pcsc)</span>
Nr.  Card  Features  Name
<span class="m">0</span>    Yes             Yubico Yubikey NEO CCID <span class="m">00</span> <span class="m">00</span>
</pre></div>
<p>Assuming everything went well you should see the Yubikey Neo listed as a detected card reader. Check your version of opensc if this is not the case, we are running version 0.13</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ opensc-tool -i
opensc <span class="m">0</span>.13.0 <span class="o">[</span>gcc  <span class="m">4</span>.8.2<span class="o">]</span>
Enabled features: zlib readline openssl pcsc<span class="o">(</span>libpcsclite.so.1<span class="o">)</span>
</pre></div>
<p>Before we continue we should make sure that the Yubikey is not only detected as a reader but also as a smart card:</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ opensc-tool --reader <span class="m">0</span> --name
PIV-II card
</pre></div>
<p>We should now be able to list the contents of the PIV applet which should be, for the time being, empty.</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ pkcs15-tool --list-data-objects
Using reader with a card: Yubico Yubikey NEO CCID <span class="m">00</span> <span class="m">00</span>
Data object <span class="s1">&#39;Card Capability Container&#39;</span>
    applicationName: Card Capability Container
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.1.219.0
    Path:            db00
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;Card Holder Unique Identifier&#39;</span>
    applicationName: Card Holder Unique Identifier
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.48.0
    Path:            <span class="m">3000</span>
    Data <span class="o">(</span><span class="m">61</span> bytes<span class="o">)</span>: 3B3019D4E739DA7...
Data object <span class="s1">&#39;Unsigned Card Holder Unique Identifier&#39;</span>
    applicationName: Unsigned Card Holder Unique Identifier
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.48.2
    Path:            <span class="m">3010</span>
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;X.509 Certificate for PIV Authentication&#39;</span>
    applicationName: X.509 Certificate <span class="k">for</span> PIV Authentication
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.1.1
    Path:            <span class="m">0101</span>
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;Cardholder Fingerprints&#39;</span>
    applicationName: Cardholder Fingerprints
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.96.16
    Path:            <span class="m">6010</span>
    Auth ID:         <span class="m">01</span>
Data object <span class="s1">&#39;Printed Information&#39;</span>
    applicationName: Printed Information
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.48.1
    Path:            <span class="m">3001</span>
    Auth ID:         <span class="m">01</span>
Data object <span class="s1">&#39;Cardholder Facial Image&#39;</span>
    applicationName: Cardholder Facial Image
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.96.48
    Path:            <span class="m">6030</span>
    Auth ID:         <span class="m">01</span>
Data object <span class="s1">&#39;X.509 Certificate for Digital Signature&#39;</span>
    applicationName: X.509 Certificate <span class="k">for</span> Digital Signature
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.1.0
    Path:            <span class="m">0100</span>
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;X.509 Certificate for Key Management&#39;</span>
    applicationName: X.509 Certificate <span class="k">for</span> Key Management
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.1.2
    Path:            <span class="m">0102</span>
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;X.509 Certificate for Card Authentication&#39;</span>
    applicationName: X.509 Certificate <span class="k">for</span> Card Authentication
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.5.0
    Path:            <span class="m">0500</span>
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;Security Object&#39;</span>
    applicationName: Security Object
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.144.0
    Path:            <span class="m">9000</span>
Data object <span class="nb">read</span> failed: File not found
Data object <span class="s1">&#39;Discovery Object&#39;</span>
    applicationName: Discovery Object
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.96.80
    Path:            <span class="m">6050</span>
    Data <span class="o">(</span><span class="m">20</span> bytes<span class="o">)</span>: 7E124F0BA0000003080000100001005F2F024000
Data object <span class="s1">&#39;Cardholder Iris Image&#39;</span>
    applicationName: Cardholder Iris Image
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.16.21
    Path:            <span class="m">1015</span>
Data object <span class="nb">read</span> failed: File not found
</pre></div>
<p>The lines containing <em>Data object read failed: File not found</em> indicate that there is currently no data loaded onto the PIV applet. Let&#39;s change that by loading a CA certificate and private key.</p>

<h2 id="importing-the-ca-certificate-and-private-key-onto-the-yubikey-neo">Importing the CA certificate and private key onto the Yubikey Neo</h2>

<p>In order to load the p12 containing the certificate and private key onto to the Yubikey Neo we need to install the yubico-piv-tool from <a href="http://opensource.yubico.com/yubico-piv-tool/releases/yubico-piv-tool-0.0.2.tar.gz">here</a></p>

<p>Let&#39;s install the packages we need to compile the yubico-piv-tool in case they would not yet be present on our system:</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ sudo apt-get install gcc autoconf libssl-dev make pcscd libccid libpcsclite-dev
</pre></div>
<p>With those in place we can continue to download and compile the yubico-piv-tool:</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ <span class="nb">cd</span> /tmp
dennisverslegers@ubuntu:/tmp$ wget http://opensource.yubico.com/yubico-piv-tool/releases/yubico-piv-tool-0.0.2.tar.gz
</pre></div><div class="highlight"><pre><span></span>dennisverslegers@ubuntu:/tmp$ tar -vxzf yubico-piv-tool-0.0.2.tar.gz
dennisverslegers@ubuntu:/tmp$ <span class="nb">cd</span> yubico-piv-tool-0.0.2
dennisverslegers@ubuntu:/tmp/yubico-piv-tool-0.0.2$ ./configure
dennisverslegers@ubuntu:/tmp/yubico-piv-tool-0.0.2$ make
dennisverslegers@ubuntu:/tmp/yubico-piv-tool-0.0.2$ sudo make install
</pre></div>
<p>Now we should be able to import our p12 container containing both the certificate and private key onto the yubikey. The yubico-piv-tool indicates that the yubikey piv applet has four distinct key slots.</p>
<div class="highlight"><pre><span></span>  -s, --slot<span class="o">=</span>ENUM        What key slot to operate on  <span class="o">(</span>possible <span class="nv">values</span><span class="o">=</span><span class="s2">&quot;9a&quot;</span>,
                           <span class="s2">&quot;9c&quot;</span>, <span class="s2">&quot;9d&quot;</span>, <span class="s2">&quot;9e&quot;</span><span class="o">)</span>

       9a is <span class="k">for</span> PIV Authentication
       9c is <span class="k">for</span> Digital Signature <span class="o">(</span>PIN always checked<span class="o">)</span>
       9d is <span class="k">for</span> Key Management
       9e is <span class="k">for</span> Card Authentication <span class="o">(</span>PIN never checked<span class="o">)</span>
</pre></div>
<p>In our case we only want to load the CA certificate onto the yubikey neo which will be used for digital signatures (of other certificates). Therefore we instruct the piv-tool to load the private key in slot 9c.</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ yubico-piv-tool -s 9c -i Documents/project1ca.p12 -K PKCS12 -p demo -a import-key -a import-cert
Successfully imported a new private key.
Successfully imported a new certificate.
</pre></div>
<p>You can verify the successful import by issuing the pkcs15-tool list data objects command again.</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ pkcs15-tool --list-data-objects
Using reader with a card: Yubico Yubikey NEO CCID <span class="m">00</span> <span class="m">00</span>
...
Data object <span class="s1">&#39;X.509 Certificate for Digital Signature&#39;</span>
    applicationName: X.509 Certificate <span class="k">for</span> Digital Signature
    applicationOID:  <span class="m">2</span>.16.840.1.101.3.7.2.1.0
    Path:            <span class="m">0100</span>
    Data <span class="o">(</span><span class="m">1159</span> bytes<span class="o">)</span>: <span class="m">53820483</span>
...
</pre></div>
<p>As you can see the Data section for X.509 Certificate for Digital Signature now indicates that data is present in this slot.With this in place we can now continue and configure openssl to use the CA certificate present on the Neo for signing of future certificate requests.</p>

<h2 id="configuring-openssl-ca-to-access-the-ca-private-key-located-on-the-yubikey-neo">Configuring OpenSSL CA to access the CA private key located on the yubikey Neo</h2>

<p>Before we can continue we need to determine the key ID of the CA private key on the piv applet for future use by OpenSSL.</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ pkcs15-tool --list-keys
Using reader with a card: Yubico Yubikey NEO CCID <span class="m">00</span> <span class="m">00</span>
Private RSA Key <span class="o">[</span>SIGN key<span class="o">]</span>
    Object Flags   : <span class="o">[</span>0x1<span class="o">]</span>, private
    Usage          : <span class="o">[</span>0x20E<span class="o">]</span>, decrypt, sign, signRecover, nonRepudiation
    Access Flags   : <span class="o">[</span>0x1D<span class="o">]</span>, sensitive, alwaysSensitive, neverExtract, <span class="nb">local</span>
    ModLength      : <span class="m">2048</span>
    Key ref        : <span class="m">156</span> <span class="o">(</span>0x9C<span class="o">)</span>
    Native         : yes
    Auth ID        : <span class="m">01</span>
    ID             : <span class="m">02</span>
    GUID           : 024fc9a7cd8f541ecad4e39ab21a95a5
</pre></div>
<p>The ID of our private key located on the Neo is indicated by the ID field, in this case 02. Take a note of this somewhere for future use.</p>

<p>Now let&#39;s continue by installing the pkcs11 OpenSSL library:</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~$ sudo apt-get install libengine-pkcs11-openssl
</pre></div>
<p>To configure OpenSSL to use the PKCS11 engine you can issue the following command from the OpenSSL prompt:</p>
<div class="highlight"><pre><span></span>OpenSSL&gt; engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:opensc-pkcs11.so
<span class="o">(</span>dynamic<span class="o">)</span> Dynamic engine loading support
Success: SO_PATH:/usr/lib/engines/engine_pkcs11.so
Success: ID:pkcs11
Success: LIST_ADD:1
Success: LOAD
Success: MODULE_PATH:opensc-pkcs11.so
Loaded: <span class="o">(</span>pkcs11<span class="o">)</span> pkcs11 engine
</pre></div>
<p><strong>Note</strong> <em>For Mac OS X the following command should be used to load the PKCS11 engine:</em></p>
<div class="highlight"><pre><span></span>engine dynamic -pre SO_PATH:/Library/OpenSC/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib/opensc-pkcs11.so
</pre></div>
<p>We can also configure OpenSSL to load the PKCS11 engine automatically at startup my modifying the openssl configuration file like so:</p>
<div class="highlight"><pre><span></span><span class="na">openssl_conf</span>            <span class="o">=</span> <span class="s">openssl_def</span>

<span class="k">[openssl_def]</span>
<span class="na">engines</span> <span class="o">=</span> <span class="s">engine_section</span>

<span class="k">[engine_section]</span>
<span class="na">pkcs11</span> <span class="o">=</span> <span class="s">pkcs11_section</span>

<span class="k">[pkcs11_section]</span>
<span class="na">engine_id</span> <span class="o">=</span> <span class="s">pkcs11</span>
<span class="na">dynamic_path</span> <span class="o">=</span> <span class="s">/usr/lib/engines/engine_pkcs11.so</span>
<span class="na">MODULE_PATH</span> <span class="o">=</span> <span class="s">/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so</span>
<span class="na">init</span> <span class="o">=</span> <span class="s">0</span>
</pre></div>
<p>Additionally you can add a pin entry in the pkcs11_section of the openssl configuration file to add the pin code to be used when accessing the smart card(s).</p>

<p>With everything in place you should be able to issue the following command to sign a certificate request using the private key located on the smartcard:</p>
<div class="highlight"><pre><span></span>dennisverslegers@ubuntu:~/Documents/demo_pki_root$ openssl ca -engine pkcs11 -keyfile <span class="m">01</span>:02 -keyform e -config ./openssl.cnf -name Project1CA -out demo_user.crt -infiles .demo_user.csr
Using configuration from ./openssl.cnf
engine <span class="s2">&quot;pkcs11&quot;</span> set.
PKCS#11 token PIN: 
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: <span class="m">5</span> <span class="o">(</span>0x5<span class="o">)</span>
        Validity
            Not Before: Apr <span class="m">28</span> <span class="m">13</span>:28:30 <span class="m">2014</span> GMT
            Not After : Apr <span class="m">28</span> <span class="m">13</span>:28:30 <span class="m">2015</span> GMT
        Subject:
            <span class="nv">countryName</span>               <span class="o">=</span> BE
            <span class="nv">stateOrProvinceName</span>       <span class="o">=</span> Vlaams-Brabant
            <span class="nv">localityName</span>              <span class="o">=</span> Leuven
            <span class="nv">organizationName</span>          <span class="o">=</span> AUSY
            <span class="nv">organizationName</span>          <span class="o">=</span> not used
            <span class="nv">organizationalUnitName</span>    <span class="o">=</span> Demo CA project
            <span class="nv">commonName</span>                <span class="o">=</span> demo_user
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Cert Type: 
                SSL Client, S/MIME
            Netscape Comment: 
                OpenSSL Generated Client Certificate
            X509v3 Subject Key Identifier: 
                2B:7C:DE:9E:B7:20:51:4E:60:4C:AD:F8:10:AF:97:2A:1D:6B:45:0D
            X509v3 Authority Key Identifier: 
                keyid:CE:9B:8C:9B:C8:59:66:42:49:1A:B4:F8:35:1B:9D:7F:D4:BC:90:75
                DirName:/C<span class="o">=</span>BE/ST<span class="o">=</span>Vlaams-Brabant/L<span class="o">=</span>Leuven/O<span class="o">=</span>AUSY/O<span class="o">=</span>not used/OU<span class="o">=</span>Demo CA project/CN<span class="o">=</span>RootCA
                serial:01

Certificate is to be certified <span class="k">until</span> Apr <span class="m">28</span> <span class="m">13</span>:28:30 <span class="m">2015</span> GMT <span class="o">(</span><span class="m">365</span> days<span class="o">)</span>
Sign the certificate? <span class="o">[</span>y/n<span class="o">]</span>:
</pre></div>
<p>Some interesting things to know:</p>

<ul>
<li>default pin: 123456</li>
<li>default unblock pin: 12345678</li>
<li>default admin key (3des key): 010203040506070801020304050607080102030405060708</li>
</ul>

<p>Needless to say it is recommended to say that changing the pin codes is absolutely mandatory. This can be done using the yubico-piv-tool.</p>
]]></content:encoded>
      </item>
  </channel>
</rss>