Add.
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
Certificate Authority with NEO
|
||||
------------------------------
|
||||
|
||||
This document explains how to set up a Certificate Authority (CA) with
|
||||
Sub-CA private keys stored on YubiKey NEOs. Typical use for this is
|
||||
to generate HTTPS certificates for internal servers.
|
||||
|
||||
Considerations
|
||||
--------------
|
||||
|
||||
For our example, we have chosen to use one root CA with a private key
|
||||
stored in an offline machine, that signs sub-CAs with private keys
|
||||
stored on YubiKey NEOs, which signs end-entity (EE) certs. We'll
|
||||
generate the Sub-CA private keys on an offline host and save a copy of
|
||||
those keys.
|
||||
|
||||
We have chosen to use a RSA 3744 bit root CA key, and RSA 2048 bit
|
||||
keys for the NEO Sub-CAs and EE certificates. The NEO is limited to
|
||||
RSA 1k and 2k keys (it supports ECDSA too but we chose to not use that
|
||||
here).
|
||||
|
||||
By setting some name constraints, we are trying to limit to powers of
|
||||
this CA. This is not fully supported by all environments, but it
|
||||
should do no harm, and may be useful in some environments.
|
||||
|
||||
The root also has a path length constraint of 1 to prevent the Sub-CAs
|
||||
from issuing further Sub-Sub-CAs.
|
||||
|
||||
We'll also set a short lifelength on the root CA to signal that expiry
|
||||
dates on root CAs are not relevant.
|
||||
|
||||
Preparations
|
||||
------------
|
||||
|
||||
We use OpenSSL to generate keys and certificates. This is done on an
|
||||
offline machine, booted from a LiveCD. Some additional packages may
|
||||
be required (pcscd, etc, see below) and will have to be transferred on
|
||||
a USB stick.
|
||||
|
||||
You need a YubiKey NEO with the PIV applet on, which you can purchase
|
||||
from Yubico.
|
||||
|
||||
You need to install the PKCS#11 Engine:
|
||||
|
||||
sudo dpkg -i libengine-pkcs11-openssl*
|
||||
|
||||
or if you are on a connected machine, more simpler:
|
||||
|
||||
sudo apt-get install libengine-pkcs11-openssl
|
||||
|
||||
Creating a Root CA
|
||||
-------------------
|
||||
|
||||
Generate the private key as follows:
|
||||
|
||||
openssl genrsa -out yubico-internal-https-ca-key.pem 3744
|
||||
|
||||
Generate the Root CA certificate and initialize the CA serial number
|
||||
counter as follows:
|
||||
|
||||
cat>yubico-internal-https-ca.conf<<EOF
|
||||
[ req ]
|
||||
x509_extensions = v3_ca
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
[ req_distinguished_name ]
|
||||
CN=Yubico Internal HTTPS CA
|
||||
[ v3_ca ]
|
||||
subjectKeyIdentifier=hash
|
||||
basicConstraints = CA:true, pathlen:1
|
||||
keyUsage=critical, keyCertSign, cRLSign
|
||||
nameConstraints=@nc
|
||||
[ nc ]
|
||||
permitted;otherName=1.3.6.1.5.5.7.8.7;IA5:yubico.com
|
||||
permitted;email.0=yubico.com
|
||||
permitted;email.1=.yubico.com
|
||||
permitted;DNS=yubico.com
|
||||
permitted;URI.0=yubico.com
|
||||
permitted;URI.1=.yubico.com
|
||||
permitted;IP.0=0.0.0.0/255.255.255.255
|
||||
permitted;IP.1=::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||
EOF
|
||||
|
||||
openssl req -new -sha256 -x509 -set_serial 1 -days 1 -config yubico-internal-https-ca.conf -key yubico-internal-https-ca-key.pem -out yubico-internal-https-ca-crt.pem
|
||||
|
||||
echo 01 > yubico-internal-https-ca-crt.srl
|
||||
|
||||
You may inspect the newly generated root CA with:
|
||||
|
||||
openssl x509 -text < yubico-internal-https-ca-crt.pem
|
||||
|
||||
Preparing a Sub-CA NEO
|
||||
----------------------
|
||||
|
||||
We need to change the management key, PIN and PUK code following the
|
||||
YubiKey-NEO-PIV-Introduction.txt document. We also want to save a
|
||||
copy of these values. Here are the steps that are needed to be done
|
||||
for each new Sub-CA NEO.
|
||||
|
||||
This step is parametrized with the name of the YubiKey NEO user.
|
||||
Generate new management code, PIN and PUK as follows:
|
||||
|
||||
user=Simon
|
||||
|
||||
key=`dd if=/dev/random bs=1 count=24 2>/dev/null | hexdump -v -e '/1 "%02X"'`
|
||||
echo $key > yubico-internal-https-$user-key.txt
|
||||
|
||||
pin=`dd if=/dev/random bs=1 count=6 2>/dev/null | hexdump -v -e '/1 "%u"'|cut -c1-6`
|
||||
echo $pin > yubico-internal-https-$user-pin.txt
|
||||
|
||||
puk=`dd if=/dev/random bs=1 count=6 2>/dev/null | hexdump -v -e '/1 "%u"'|cut -c1-8`
|
||||
echo $puk > yubico-internal-https-$user-puk.txt
|
||||
|
||||
Configure a fresh NEO with these parameters as follows:
|
||||
|
||||
yubico-piv-tool -a set-mgm-key -n $key
|
||||
yubico-piv-tool -k $key -a change-pin -P 123456 -N $pin
|
||||
yubico-piv-tool -k $key -a change-puk -P 12345678 -N $puk
|
||||
|
||||
Creating a Sub-CA
|
||||
-----------------
|
||||
|
||||
This step is parametrized with the name of the YubiKey NEO user. This
|
||||
means we will have one Sub-CA for every person authorized to sign
|
||||
certificates in our CA.
|
||||
|
||||
user=Simon
|
||||
|
||||
We first need to load the management key and PIN code from the
|
||||
previous section.
|
||||
|
||||
key=`cat yubico-internal-https-$user-key.txt`
|
||||
pin=`cat yubico-internal-https-$user-pin.txt`
|
||||
|
||||
Generate the private key:
|
||||
|
||||
openssl genrsa -out yubico-internal-https-subca-$user-key.pem 2048
|
||||
|
||||
Generate the Sub-CA certificate:
|
||||
|
||||
cat>yubico-internal-https-subca-$user-csr.conf<<EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
[ req_distinguished_name ]
|
||||
CN=Yubico Internal HTTPS $user Sub-CA
|
||||
EOF
|
||||
|
||||
openssl req -sha256 -new -config yubico-internal-https-subca-$user-csr.conf -key yubico-internal-https-subca-$user-key.pem -nodes -out yubico-internal-https-subca-$user-csr.pem
|
||||
|
||||
cat>yubico-internal-https-subca-$user-crt.conf<<EOF
|
||||
basicConstraints = CA:true, pathlen:0
|
||||
keyUsage=critical, keyCertSign
|
||||
EOF
|
||||
|
||||
openssl x509 -sha256 -CA yubico-internal-https-ca-crt.pem -CAkey yubico-internal-https-ca-key.pem -req -in yubico-internal-https-subca-$user-csr.pem -extfile yubico-internal-https-subca-$user-crt.conf -out yubico-internal-https-subca-$user-crt.pem
|
||||
|
||||
echo 00 > yubico-internal-https-subca-$user-crt.srl
|
||||
|
||||
You may inspect the newly generated EE cert with this command:
|
||||
|
||||
openssl x509 -text < yubico-internal-https-subca-$user-crt.pem
|
||||
|
||||
Import Sub-CA key to NEO:
|
||||
|
||||
yubico-piv-tool -k $key -a import-key -s 9c < yubico-internal-https-subca-$user-key.pem
|
||||
|
||||
Import Sub-CA cert to NEO:
|
||||
|
||||
yubico-piv-tool -k $key -a import-certificate -s 9c < yubico-internal-https-subca-$user-crt.pem
|
||||
|
||||
Creating End-Entity Certificates
|
||||
--------------------------------
|
||||
|
||||
This step is parametrized with the hostname, and the name of the
|
||||
Sub-CA used to sign the EE, so set it first:
|
||||
|
||||
host=munin
|
||||
user=Simon
|
||||
|
||||
Then generate a new private key and certificate request:
|
||||
|
||||
openssl genrsa -out yubico-internal-https-ee-$host-key.pem 2048
|
||||
|
||||
cat>yubico-internal-https-ee-$host-csr.conf<<EOF
|
||||
[ req ]
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
[ req_distinguished_name ]
|
||||
CN=ee-$host.yubico.com
|
||||
EOF
|
||||
openssl req -sha256 -new -config yubico-internal-https-ee-$host-csr.conf -key yubico-internal-https-ee-$host-key.pem -nodes -out yubico-internal-https-ee-$host-csr.pem
|
||||
|
||||
Then sign the certificate using the NEO:
|
||||
|
||||
cat>yubico-internal-https-ee-$host-crt.conf<<EOF
|
||||
EOF
|
||||
|
||||
openssl << EOT
|
||||
engine dynamic -pre SO_PATH:/usr/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre NO_VCHECK:1 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -pre VERBOSE
|
||||
x509 -engine pkcs11 -CAkeyform engine -CAkey slot_1-id_2 -sha256 -CA yubico-internal-https-subca-$user-crt.pem -req -passin pass:$pin -in yubico-internal-https-ee-$host-csr.pem -extfile yubico-internal-https-ee-$host-crt.conf -out yubico-internal-https-ee-$host-crt.pem
|
||||
EOT
|
||||
|
||||
You may inspect the newly generated EE cert with this command:
|
||||
|
||||
openssl x509 -text < yubico-internal-https-ee-$host-crt.pem
|
||||
Reference in New Issue
Block a user