Certificate Authentication Setup

This guide will provide an example on how to create a minimal CA setup for HTTP and SSH authentication. The guide will also show how to use a YubiKey 5C hardware token.

Prerequisites

The guide uses OpenSSL, OpenSSH, and Yubico command line tools. It is intended mainly for Linux or OSX setups. On Windows it is recommended to use a Linux virtual machine to perform the steps.

Ubuntu 20.10 will be used as a reference for Linux.

On Ubuntu and OSX, OpenSSL and OpenSSH should be available out of the box.
On Ubuntu, the Yubico tools can be installed from official repositories with the following command:

sudo apt install yubico-piv-tool ykcs11 yubikey-manager

On OSX, the Yubico tools can be installed from Homebrew with the following command:

brew install ykman yubico-piv-tool

Some of the used commands require the Yubikey PIN and management key, the default values for the Yubikey 5C are the following:

PIN: 123456
Management Key: 010203040506070801020304050607080102030405060708

More information on YubiKey defaults are available at:

https://developers.yubico.com/yubico-piv-tool/YubiKey_PIV_introduction.html

Preparing the YubiKey

In order to use Smart Cards on some platforms, the CHUID must be set and the slots 9a and 9c should have a key and a certificate. If this has not already been done, a key and the corresponding certificate needs to be loaded in the YubiKey slot 9c.

yubico-piv-tool -a generate -s 9d -k --pin-policy=once --touch-policy=always --algorithm=RSA2048 -o manager_key_pkcs8.pub
yubico-piv-tool -a verify-pin -a request-certificate -s 9d -S '/CN=manager/OU=everyware_iot/O=eurotech.com/' -i manager_key_pkcs8.pub -o manager.csr
openssl x509 -req -in manager.csr -CA ca.crt -CAkey ca_key -CAcreateserial -out manager.crt
yubico-piv-tool -k -a import-certificate -s 9d -i manager.crt
yubico-piv-tool -a status

Reset the Card Holder Unique Identifier.

yubico-piv-tool -a set-ccc
yubico-piv-tool -a set-chuid

The PIN can be changed with the following command:

yubico-piv-tool -a change-pin

Certificate authority

We start by creating the private/public key pair for the Certificate Authority. For RSA keys, we can use OpenSSL toolset or the OpenSSH toolset, as the Private Keys are interchangeable in PEM format.

Use the following commands to generate an RSA private/public key pair using the OpenSSL toolset. It will generate private and public key in PEM format. Then, use ssh-keygen to convert the public key into SSH format.

openssl genrsa -out ca_key 2048
chmod 400 ca_key
openssl req -new -x509 -key ca_key -out ca.crt
openssl rsa -in ca_key -RSAPublicKey_out -out ca_key_pem.pub
ssh-keygen -i -m PEM -f ca_key_pem.pub > ca_key.pub

In order to use the created CA for Web UI login, the content of the ca.crt file can be added as a Https Client Certificate in the Security -> Certificate List section. ESF must be restarted in order to make the change effective.

Configure SSH Access

An SSH sever can be configured to accept User's Certificate during the login process. Such configuration can be performed at Linux user level or at system level for all Linux users.

Configure SSH at System Level

To configure the SSH server to allow for user's certificate logins, copy the ca_key.pub on the path /etc/ssh/ca_key.pub. Then, edit /etc/ssh/sshd_config and add the following lines at the end:

PubkeyAuthentication yes
TrustedUserCAKeys /etc/ssh/ca_key.pub

Configure SSH at User Level

Create an SSH authorized_keys file and indicate that the key should be trusted as a certificate authority to validate proprietary OpenSSH certificates for authenticating as that user. This is achieved by adding the cert-authority prefix in the authorized_keys file. In this way, all identities signed by the CA will be allowed to login.

Finally, copy the authorized_keys file to the target server in the home directory of the target Linux account under ~/.ssh/ authorized_keys path.

sed 's/^/cert-authority /' ca_key.pub > authorized_keys
scp authorized_keys ${login}@${server}:/home/${login}/.ssh/authorized_keys

Generating a credential

This section shows how to generate a credential with the YubiKey or with OpenSSL, in case an hardware token is not available.
If the YubiKey is used, the private key will never leave the hardware token.

Private key on the filesystem

The following step illustrate how to create a user x509 using OpenSSL, the associated public key is is then converted into SSH format.

Generate the user private key using OpenSSL.

openssl genrsa -out user_key_openssl 2048
chmod 400 user_key_openssl

The next step involves creating a CSR.
In order to use the User's Certificate to perform a login on ESF Web UI, it is necessary to set the Common Name appropriately. See the ESF Web UI Client Authentication section before continuing, the step below creates a certificate that allows to log in as the admin ESF identity.

openssl req -new -key user_key_openssl -subj '/CN=admin/OU=everyware_iot/O=eurotech.com/' -out user_openssl.csr

The following step extracts the public key and converts it in SSH format:

openssl rsa -in user_key_openssl -RSAPublicKey_out -out user_key_openssl_pem.pub
ssh-keygen -i -m PEM -f user_key_openssl_pem.pub > user_key_openssl.pub

The CSR can be signed using the CA certificate created before in order to create a certificate that can be used for HTTPS authentication:

openssl x509 -req -in user_openssl.csr -CA ca.crt -CAkey ca_key -CAcreateserial -out user_openssl.crt

The certificate and private key can be exported in a PKCS12 keystore file that can be later imported in system keychain and/or browser:

openssl pkcs12 -export -out user_credential.pfx -inkey user_key_openssl -in user_openssl.crt

The command will require to define an export password to protect the keystore.

Then, the following commands will create an SSH user's certificate by signing the user's public key with the ssh-keygen tool. The commands below create a certificate that allows to login as the acme user. If you are using a different Linux user, you might want to change the value of the -n argument in the second line.

ssh-keygen -s ca_key -I admin -n acme user_key_openssl.pub
ssh-keygen -Lf user_key_openssl-cert.pub

Private key on the YubiKey

User's identiy can be created and stored as a resident key within YubiKey. The following commands create a private RSA key in the YubiKey 5C in slot 9a.

To create the private key you will be asked to enter the YubiKey Management Key and then to touch the key. After the first command, the private key will be stored in the YubiKey slot 9a and the public key will be in the file system in PKCS8 format.

yubico-piv-tool -a generate -s 9a -k --pin-policy=once --touch-policy=never --algorithm=RSA2048 -o user_key_pkcs8.pub

The --pin-policy and --touch-policy parameters allow to configure wether it is necessary to enter YubiKey PIN and/or touch the hardware token in order to allow credential access.

The next command will create a Certificate Signing Request (CSR) to have the pubic key signed by the Certificate Authority. The create the CSR, you will be asked to enter the YubiKey PIN and then to touch the key.
As done in the previous section, the step below creates a certificate that allows to log in as the admin ESF Web UI identity.

yubico-piv-tool -a verify-pin -a request-certificate -s 9a -S '/CN=admin/OU=everyware_iot/O=eurotech.com/' -i user_key_pkcs8.pub -o user.csr

The following commands will sign the user's CSR with CA and we will then import the resulting X.509 Certificate in the YubiKey 9a slot.

openssl x509 -req -in user.csr -CA ca.crt -CAkey ca_key -CAcreateserial -out user.crt
yubico-piv-tool -k -a import-certificate -s 9a -i user.crt
yubico-piv-tool -a status

Then, the following commands will create an SSH user's certificate by signing the user's public key with the ssh-keygen tool. As done in the previous section, the commands below create a certificate that allows to login as the acme user. If you are using a different Linux user, you might want to change the value of the -n argument in the second line.

ssh-keygen -i -m PKCS8 -f user_key_pkcs8.pub > user_key.pub
ssh-keygen -s ca_key -I admin -n acme user_key.pub
ssh-keygen -Lf user_key-cert.pub

The user SSH certificate cannot be stored on the YubiKey, it must be made available on the machine that is used for login.

Using the credential for SSH login

Private key on the filesystem

In order to login using SSH, the follwoing command can be used:

ssh -i user_key_openssl acme@${device-ip}

${device-ip} should be replaced with the IP address of the gateway.

The user_key_openssl and user_key_openssl-cert.pem files must be in the working directory. As an alternative, it is possible to copy these files to the .ssh subfolder of the home directory of current user.

Private key on YubiKey

SSH login with the YubuKey can be performed with the following commands, that vary depending on the platform. Replace ${device-ip} with the gateway IP address:

OSX

ssh -I /usr/local/lib/libykcs11.dylib -i user_key-cert.pub acme@${device-ip}

### Ubuntu

ssh -I /usr/lib/x86_64-linux-gnu/libykcs11.so -i user_key-cert.pub acme@${device-ip}

Windows

Windows 10 provides an OpenSSH version out of the box, but that version does not include PKCS11 support. An updated version with PKCS11 support can be downloaded from https://github.com/PowerShell/Win32-OpenSSH/releases/tag/v8.1.0.0p1-Beta.

The PKCS11 driver can be obtained installing the yubico-piv-tool package from https://developers.yubico.com/yubico-piv-tool/Releases/.

The C:\Program Files\Yubico\Yubico PIV Tool\bin folder must be added to the PATH environment variable before attempting to log in.

Once this is done login can be performed with the following command:

${ssh command} -I 'C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll' -i user_key-cert.pub acme@${device-ip}

Where ${ssh command} is the path to the ssh binary downloaded previously.

As an alternative, it is possible to use a Linux virtual machine to perform ssh login.

Using the credential for HTTPS login

It is possible to use the x509 certificates and private keys generated previously to perform HTTPS login.
This can be done either using the YubiKey or by using the private keys generated using OpenSSL.

It might be necessary to perform some preliminary steps on the machine used for login. This involves for example importing the private key and certificate in browser/system keystore or configuring the environment to use the YubiKey.

During login process, the browser might prompt the user to pick the certificate to be user and/or insert YubiKey PIN.
If the corresponding setting has been enabled during certificate creation, it might also be necessary to touch the YubiKey in order to login.

Requirements

In order to perform a successful login, the client must present a certificate chain that has been signed by one of the configured CAs. The Common Name of the leaf certificate of the chain must be set to the identity name (e.g. "admin").

In order to add a CA perform the following steps:

  1. Access to the Web UI using password authentication and navigate to the Security -> Certificates List section.
  2. Press the Add button, select Https Client Certificate from the list
  3. Paste the CA certificate in PEM format in the Certificate field (the content of the ca.crt file).

Mozilla Firefox

Importing a PKCS12 credential

In order to import a credential from a PKCS12 store perform the following steps:

  • Open Firefox preferences
  • Select Privacy & Security
  • Click on the View Certificates... button in the Certificates section
  • Click on the Import button in the Your Certificates tab and select the pfx file
  • Enter the store password

Tested on Firefox 85.0.1

YubiKey

Firefox provides a built in PKCS11 implementation and can interact with the Yubico YKCS11 driver directly on Linux, Windows and OSX.
Use the following instructions to add YKCS11 as a security device to Mozilla Firefox.

https://developers.yubico.com/yubico-piv-tool/YKCS11/Supported_applications/firefox.html.

The instructions require to select the Yubico YKCS11 driver, that should be available at the following locations after installing the prerequisites on each platform:

  • Ubuntu: /usr/lib/x86_64-linux-gnu/libykcs11.so
  • OSX: /usr/local/lib/libykcs11.dylib
  • Windows : C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll

You will be prompted to enter the YubiKey PIN and to select an Identitfy from the YubiKey
After selecting the Identity in the 9a slot and touching the YubiKey will be allowed to login.

Safari or Chrome on OSX

Importing a PKCS12 credential

In order to import a certificate and private key, perform the following steps:

  • Open the Keychain Access application
  • Select the login keychain
  • Select File -> Import items
  • Select the pfx file
  • Enter the store password

At this point it should be possible to use the certificate in Chrome and Safari. OSX might prompt for the local user password to grant access to the certificate and private key upon login.
Selecting the Always Allow button in the dialog should allow to prevent this.

Tested on OSX Catalina.

YubiKey

Safari and Chrome use the macOS Keychain to select the SSL Identity. The YubiKey should work out of the box.

Microsoft Edge or Chrome on Windows 10

Importing a PKCS12 credential

In order to import a certificate and private key, it should be enough to double click on the pfx file and follow the instructions, the wizard will ask for the store password.
Once the credential has been imported, Chrome and Edge will allow to select it for login.

YubiKey

On the Windows platform, Edge and Chrome use the operating system APIs to interact with the Yubikey and should work out of the box.

Appendix: Using an intermediate CA for HTTPS and SSH authentication

HTTPS

Using an intermediate CA is supported both with and without a YubiKey, with the following caveats:

  1. The intermediate CA certificate must have at least the following extension in order for it to be accepted by Jetty:
     X509v3 extensions:  
                X509v3 Basic Constraints:  
                    CA:TRUE
    
  2. The intermediate CA certificate must be presented by the browser along with the leaf certificate.
    1. Private key on the filesystem: In this case it is possible to add the intermediate CA certificate in the PCKS12 export file along with leaf certificate, for doing this, the -certfile argument can be added to the command in the guide:
      openssl pkcs12 -export -out user_credential.pfx -in user.crt -inkey user_key -certfile intermediate.crt
    2. Private key on YubiKey: The intermediate CA certificate cannot be stored on the YubiKey, it must be added to system Keychain or to the browser
    3. As an alternative it should be possible to add the intermediate CA certificate to the HTTPS keystore of gateway.

SSH

SSH public key authentication does not seem to have a concept of intermediate keys. If the goal is using the same key for HTTPS and SSH, and the leaf HTTPS certificate has been signed using an intermediate CA, then the public key associated with the intermediate CA must be used at system level on the SSH server.