Repository

https://github.com/jlangenegger/ssh_certificate/

Sign client's public keys

To sign client's public keys there is the script 'generate_client_certificate.sh' to simplify the procedure.
The scripts does have the following options:

The output of 'generate_client_certificate.sh' is a .tar archive that contains the certificate, the public key that is used to authenticate servers as well as an instruction to install the certificate on the client's machine. It is stored in the home directory '$HOME/signed_keys'.

Sign hosts's public keys

To sign host's public keys there is the script 'generate_host_certificate.sh' to simplify the procedure.
The scripts does have the following options:

The output of 'generate_host_certificate.sh' is the certificate 'HOST_ID-cert.pub' that needs to be copied to the host. It is stored in the home directory '$HOME/signed_keys'.

Prepare Yubikey

This needs to be done on a offline machine!

Install libraries that are later used

To setup the yubikey the yubico-piv-tool is used. It must be installed from source to work correctly. For the installation the following packages are needed:

apt-get install autoconf automake build-essential libtool libssl-dev pkg-config check libpcsclite-dev gengetopt help2man

Install the tool

git clone https://github.com/Yubico/yubico-piv-tool.git

cd yubico-piv-tool

autoreconf --install
./configure  --disable-dependency-tracking
make
make install

Change default pins and management key of yubikey

To prepare the PIV applet in the YubiKey the management key, the pin and the punk needs to be set.

YUBIKEYNUM=0
key=`dd if=/dev/random bs=1 count=24 2>/dev/null | hexdump -v -e '/1 "%02X"'`
echo $key > yubikey$YUBIKEYNUM.key
pin=`dd if=/dev/random bs=1 count=6 2>/dev/null | hexdump -v -e '/1 "%u"'|cut -c1-6`
echo $pin > yubikey$YUBIKEYNUM.pin
puk=`dd if=/dev/random bs=1 count=6 2>/dev/null | hexdump -v -e '/1 "%u"'|cut -c1-8`
echo $puk > yubikey$YUBIKEYNUM.puk

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

Generate RSA private keys for SSH Host CA

Then generate a RSA private key for the SSH Host CA, and generate a dummy X.509 certificate for that key. The only use for the X.509 certificate is to make PIV/PKCS#11 happy. They want to be able to extract the public-key from the smart-card, and do that through the X.509 certificate.

openssl genrsa -out yubikey$YUBIKEYNUM-key.pem 2048
openssl req -new -x509 -batch -key yubikey$YUBIKEYNUM-key.pem -out yubikey$YUBIKEYNUM-cert.pem

Import keys to yubikey

You import the key and certificate to the PIV applet as follows:

yubico-piv-tool -k $key -a import-key -s 9c < yubikey$YUBIKEYNUM-key.pem
yubico-piv-tool -k $key -a import-certificate -s 9c < yubikey$YUBIKEYNUM-cert.pem

Extract public key

Extract the public key for the CA:

PATH_TO_CERTIFICATE="/etc/ssh-ca"
PATH_TO_YKCS11="/usr/local/lib/libykcs11.so"

mkdir -p $PATH_TO_CERTIFICATE
ssh-keygen -D $PATH_TO_YKCS11 -e > $PATH_TO_CERTIFICATE/yubikey$YUBIKEYNUM.pub

Sign server's RSA key

PATH_TO_CERTIFICATE="/etc/ssh-ca"
PATH_TO_YKCS11="/usr/local/lib/libykcs11.so"

ssh-keygen  -D $PATH_TO_YKCS11
            -s $PATH_TO_CERTIFICATE/yubikey$YUBIKEYNUM.pub
            -I server_name \
            -h \
            -n server.netdef.org \
            -V +52w \
            /etc/ssh-ca/ssh_host_rsa_key.pub

Options explanation:

Sign client's RSA key

PATH_TO_CERTIFICATE="/etc/ssh-ca"
PATH_TO_YKCS11="/usr/local/lib/libykcs11.so"

ssh-keygen  -D $PATH_TO_YKCS11
            -s $PATH_TO_CERTIFICATE/yubikey$YUBIKEYNUM.pub
            -I client_name \
            -n root \
            -V +24h \
            /etc/ssh_ca/id_rsa.pub

Options explanation:

Troubleshooting

Reset PIV on Yubikey

yubico-piv-tool -averify-pin -P471112
yubico-piv-tool -averify-pin -P471112
yubico-piv-tool -averify-pin -P471112
yubico-piv-tool -averify-pin -P471112
yubico-piv-tool -achange-puk -P471112 -N6756789
yubico-piv-tool -achange-puk -P471112 -N6756789
yubico-piv-tool -achange-puk -P471112 -N6756789
yubico-piv-tool -achange-puk -P471112 -N6756789
yubico-piv-tool -areset
yubico-piv-tool -aset-chuid
yubico-piv-tool -aset-ccc

Viewing an SSH certificate

ssh-keygen -L -f hello_world-cert.pub
hello_world-cert.pub:
        Type: ssh-rsa-cert-v01@openssh.com host certificate
        Public key: RSA-CERT SHA256:Ciqze7DghNb2VtOoxeslkJXGIikFWY8BQM3E7KMQS/0
        Signing CA: RSA SHA256:l/ccLllvZ9FD+Isv8tLx+2H5Hk6ctzlyoDTTfaY6M+U
        Key ID: "hello_world"
        Serial: 0
        Valid: from 2020-05-29T06:09:00 to 2021-05-28T06:10:37
        Principals:
                hello_world.netdef.org
        Critical Options: (none)
        Extensions: (none)