Certificates

The certificate chain of Guardian is:

S15 Root CA
|
+--S15 QKD intermediate CA
   |
   +--KME operator intermediate CA (kme)
      |
      +--Internal Intermediate CA (generated by ``cert_auth``)
      |  |
      |  +-- Vault server certificate
      |  +-- Vault client certificate (``vault_init``)
      |
      +--Vault PKI engine Intermediate CA
         |
         +-- Service client certificates, ``rest``, ``watcher``
         +-- SAE client certificates

In order to verify an identity through TLS mutual authentication, both server and client present their certificates with or without their CA chain. They will then verify the others certificates with their trusted CA chains to determine the authenticity of the certificates before deciding to continue with the connection.

Additional Clients

To add additional individual SAE clients, the KME will need to verify the authenticity of the SAEs. One way to do this is for the SAE to present a Certificate Signing Request to be signed by the Vault PKI engine Intermediate CA. The mandatory identifier needed by Guardian is the

  1. Common Name

Recommended identifiers are

  1. Country

  2. State

  3. Locality

  4. Organisation Unit

Tip

As of 2021, a minimum key length of 2048-bit RSA or 256-bit ECC for client certificate signing is strongly recommended.


Certificate Signing

Once the client presents his/her CSR, the QKD device controller can sign it and issue a certificate together with the chain for the client to use.

Warning

Signing a CSR and issuing a certificate implies that the client will be able authenticate using his key and certificate chain to any server that trusts the same CA chain. As such always verify the identity of the client making the CSR before signing it.

We show examples of signing the CSR through Vault GUI via a web browser, Vault API https requests and Python hvac.’

In this example, we created an entity named controller that can authenticate via username/password, TLS certificate and/or tokens. controller has access to the PKI engine secrets enabled at the /pki_int path in Vault.

GUI

This example uses the Vault GUI via a TLS enabled Web browser. A certificate that can authenticate to the Vault UI at port 8200 needs to be already installed. Navigate to the Vault UI page which is https://kme1:8200/ui/vault/auth in this example. Since we are authenticating via username/password in this GUI example, select Username under Method and insert username and password.

Vault login screen with username login method

The controller is authorized to log in to Vault UI via username and password

PKI secrets engine for issuing/signing certificates

Once logged in, the controller can see the /pki_int secrets engine. He/She however cannot access the KV secrets that holds the QKDkeys.

Intermediate CA role

Inside the /pki_int engine, the role_int_ca_cert_issuer role is enabled and the QKD device controller can generate and/or sign certificates.

Certificate signing request with options

Copy the CSR from the client into the textbox. It is not recommended to sign verbatim unless the client is highly trusted. Set a unique common name for the client to overwrite the default in the CSR. DNS/Email and IP SANs may also be set. Other SANs will need a valid Object identifier to be able to be assigned. Also the role needs to be set up to allow the other SANs.

Certificate signed with CA chain

Once signed, the certificate can be given back to the client together with the Chain and he/she can now use the cert and key together to authenticate to Guardian.

Vault API

In this example we show how to sign the CSR with Vault API. To use this method, a Token is required. First we obtain the token using the controller TLS certificate and the /auth/cert/login backend.

{
   "name": "controller_cert"
}

where controller_cert is the cert_name that is defined in the cert authentication method.

Using the Client token we now send the following POST request

{
   "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIBPTCBxAIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh\nMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMHYwEAYHKoZIzj0CAQYF\nK4EEACIDYgAEZQ923Hm0z1/EV6jmlRsFgCbUQTFxY8jOUXlGK0aBXiNNZsv2vBap\n/amG5KrBIN/H5BDDMULmw9ANOGDXr+DJcjXoA/lymZIxjEp3ufJrVeaTvZpnBrtg\nigf/sAliuKjkoAAwCgYIKoZIzj0EAwIDaAAwZQIxAP/dUltIUEJ4qlUyX9jfPOcx\n7fzegJ4thWdnwu4hCTx64htl5tsYVM04+W5FvHeQhgIwRyXPJi87masJT9qqbBpb\nlsFAv7Wp2YwJRJXQAl5fV2nBEHvQgR2MBnyTBFIFDh5q\n-----END CERTIFICATE REQUEST-----",
   "common_name": "unique_sae_id"
}

Where the Token is the one obtain in the previous request.

Note that the new lines needs to be formatted as \n in JSON.


HVAC

Finally using the hvac client, we can similarly Sign a Certificate with the following python command with the necessary credentials.

 1import hvac
 2client = hvac.Client(
 3         url="https://kme1:8200/",
 4         cert=("cert.pem","key.pem"),
 5         verify="cacert.pem")
 6
 7client.auth_tls()
 8sign_certificate_response =   client.secrets.pki.sign_certificate(
 9                              mount_point='pki_int',
10                              name='role_int_ca_cert_issuer',
11                              csr='-----BEGIN CERTIFICATE REQUEST-----\nMIIBPTCBxAIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh\nMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMHYwEAYHKoZIzj0CAQYF\nK4EEACIDYgAEZQ923Hm0z1/EV6jmlRsFgCbUQTFxY8jOUXlGK0aBXiNNZsv2vBap\n/amG5KrBIN/H5BDDMULmw9ANOGDXr+DJcjXoA/lymZIxjEp3ufJrVeaTvZpnBrtg\nigf/sAliuKjkoAAwCgYIKoZIzj0EAwIDaAAwZQIxAP/dUltIUEJ4qlUyX9jfPOcx\n7fzegJ4thWdnwu4hCTx64htl5tsYVM04+W5FvHeQhgIwRyXPJi87masJT9qqbBpb\nlsFAv7Wp2YwJRJXQAl5fV2nBEHvQgR2MBnyTBFIFDh5q\n-----END CERTIFICATE REQUEST-----',
12                              common_name='unique_sae_id')
13print('Signed certificate: {}'.format(sign_certificate_response))

The response will be the same as the response in Vault API