How to configure the server TLS certificates for authentication

Author: Zbigniew Kurzynski zbigniew.kurzynski@intel.com

Created: May 8, 2020

Related documents:

Introduction

With help of this guidebook you should be able to create both client and server certificates signed by a CA that can be used to authenticate user requests to an OpenBMC server. You will also learn how to enable and test the OpenBMC TLS authentication.

Certificates

For a certificate to be marked as valid, it (and every certificate in the chain) has to meet these conditions:

  • KeyUsage contains required purpose digitalSignature and keyAgreement (see rfc 3280 4.2.1.3)
  • ExtendedKeyUsage contains required purpose clientAuth for client certificate and serverAuth for server certificate (see rfc 3280 4.2.1.13)
  • public key meets minimal bit length requirement
  • certificate has to be in its validity period
  • notBefore and notAfter fields have to contain valid time
  • has to be properly signed by certificate authority
  • certificate is well-formed according to X.509
  • issuer name has to match CA's subject name for client certificate
  • issuer name has to match the fully qualified domain name of your OpenBMC host

If you already have certificates you can skip to Enable TLS authentication or go to Verify certificates and check if they meet the above requirements.

Prepare configuration files

To generate certificates with required parameters some modification must be made to the default openssl configuration file.

First create a new folder named ca and create a configuration file using the default configuration as a template (we do not want to change the original one). The location of the configuration file may vary depending on the operating system. For Ubuntu it is usually /usr/lib/ssl/openssl.cnf, but can also can be at /etc/ssl/openssl.cnf. For Cygwin it might be /etc/defaults/etc/pki/tls/openssl.cnf or /etc/pki/tls/openssl.cnf.

mkdir ~/ca
cd ~/ca
cp /usr/lib/ssl/openssl.cnf openssl-client.cnf

Then open the client ~/ca/openssl-client.cnf file in your favorite editor, for example vi.

vi ~/ca/openssl-client.cnf

Find the sections listed below and add or choose the presented values.

[ req ]
req_extensions = v3_req

[ usr_cert ]
extendedKeyUsage = clientAuth

[ v3_req ]
extendedKeyUsage = clientAuth
keyUsage = digitalSignature, keyAgreement

Now create a server configuration openssl-server.cnf by copying the client file

cp ~/ca/openssl-client.cnf openssl-server.cnf

and changing values presented in the sections listed below.

[ usr_cert ]
extendedKeyUsage = serverAuth

[ v3_req ]
extendedKeyUsage = serverAuth

Create two additional configuration files myext-client.cnf and myext-server.cnf for the client and server certificates respectively. Without these files no extensions are added to the certificate.

cat << END > myext-client.cnf
[ my_ext_section ]
keyUsage = digitalSignature, keyAgreement
extendedKeyUsage = clientAuth
authorityKeyIdentifier = keyid
END
cat << END > myext-server.cnf
[ my_ext_section ]
keyUsage = digitalSignature, keyAgreement
extendedKeyUsage = serverAuth
authorityKeyIdentifier = keyid
END

Create a new CA certificate

First we need to create a private key to sign the CA certificate.

openssl genrsa -out CA-key.pem 2048

Now we can create a CA certificate, using the previously generated key. You will be prompted for information which will be incorporated into the certificate, such as Country, City, Company Name, etc.

openssl req -new -config openssl-client.cnf -key CA-key.pem -x509 -days 1000 -out CA-cert.pem

Create client certificate signed by given CA certificate

To create a client certificate, a signing request must be created first. For this another private key will be needed.

Generate a new key that will be used to sign the certificate signing request:

openssl genrsa -out client-key.pem 2048

Generate a certificate signing request.

You will be prompted for the same information as during CA generation, but provide the OpenBMC system user name for the CommonName attribute of this certificate. In this example, use root.

openssl req -new -config openssl-client.cnf -key client-key.pem -out signingReqClient.csr

Sign the certificate using your CA-cert.pem certificate with following command:

openssl x509 -req -extensions my_ext_section -extfile myext-client.cnf -days 365 -in signingReqClient.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out client-cert.pem

The file client-cert.pem now contains a signed client certificate.

Create server certificate signed by given CA certificate

For convenience we will use the same CA generated in paragraph Create a new CA certificate, although a different one could be used.

Generate a new key that will be used to sign the server certificate signing request:

openssl genrsa -out server-key.pem 2048

Generate a certificate signing request. You will be prompted for the same information as during CA generation, but provide the fully qualified domain name of your OpenBMC server for the CommonName attribute of this certificate. In this example it will be bmc.example.com. A wildcard can be used to protect multiple host, for example a certificate configured for *.example.com will secure www.example.com, as well as mail.example.com, blog.example.com, and others.

openssl req -new -config openssl-server.cnf -key server-key.pem -out signingReqServer.csr

Sign the certificate using your CA-cert.pem certificate with following command:

openssl x509 -req -extensions my_ext_section -extfile myext-server.cnf -days 365 -in signingReqServer.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out server-cert.pem

The file server-cert.pem now contains a signed server certificate.

Verify certificates

To verify the signing request and both certificates you can use following commands.

openssl x509 -in CA-cert.pem -text -noout
openssl x509 -in client-cert.pem -text -noout
openssl x509 -in server-cert.pem -text -noout
openssl req -in signingReqClient.csr -noout -text
openssl req -in signingReqServer.csr -noout -text

Below are example listings that you can compare with your results. Pay special attention to attributes like:

  • Validity in both certificates,
  • Issuer in client-cert.pem, it must match to Subject in CA-cert.pem,
  • Section X509v3 extensions in client-cert.pem it should contain proper values,
  • Public-Key length, it cannot be less than 2048 bits.
  • Subject CN in client-cert.pem, it should match existing OpemBMC user name. In this example it is root.
  • Subject CN in server-cert.pem, it should match OpemBMC host name. In this example it is **bmc.example.com **. (see rfc 3280 4.2.1.11 for name constraints)

Below are fragments of generated certificates that you can compare with.

CA-cert.pem
    Data:
        Version: 3 (0x2)
        Serial Number: 16242916899984461675 (0xe16a6edca3c34f6b)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
        Validity
            Not Before: May 11 11:40:48 2020 GMT
            Not After : Feb  5 11:40:48 2023 GMT
        Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d4:24:c1:1d:ac:85:8c:5b:42:e4:f8:a8:d8:7c:
                    ...
                    55:83:8b:aa:ac:ac:6e:e3:01:2b:ce:f7:ee:87:21:
                    f9:2b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
            X509v3 Authority Key Identifier:
                keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE

            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         cc:8b:61:6a:55:60:2b:26:55:9f:a6:0c:42:b0:47:d4:ec:e0:
         ...
         45:47:91:62:10:bd:3e:a8:da:98:33:65:cc:11:23:95:06:1b:
         ee:d3:78:84
client-cert.pem
    Data:
        Version: 3 (0x2)
        Serial Number: 10150871893861973895 (0x8cdf2434b223bf87)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
        Validity
            Not Before: May 11 11:42:58 2020 GMT
            Not After : May 11 11:42:58 2021 GMT
        Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=root
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cf:d6:d0:a2:09:62:df:e9:a9:b1:e1:3d:7f:2f:
                    ...
                    30:7b:48:dc:c5:2c:3f:a9:c0:d1:b6:04:d4:1a:c8:
                    8a:51
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage:
                Digital Signature, Key Agreement
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Authority Key Identifier:
                keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE

    Signature Algorithm: sha256WithRSAEncryption
         7f:a4:57:f5:97:48:2a:c4:8e:d3:ef:d8:a1:c9:65:1b:20:fd:
         ...
         25:cb:5e:0a:37:fb:a1:ab:b0:c4:62:fe:51:d3:1c:1b:fb:11:
         56:57:4c:6a
server-cert.pem
    Data:
        Version: 3 (0x2)
        Serial Number: 10622848005881387807 (0x936beffaa586db1f)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com
        Validity
            Not Before: May 22 13:46:02 2020 GMT
            Not After : May 22 13:46:02 2021 GMT
        Subject: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d9:34:9c:da:83:c6:eb:af:8f:e8:11:56:2a:59:
                    ...
                    92:60:09:fc:f9:66:82:d0:27:03:44:2f:9d:6d:c0:
                    a5:6d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage:
                Digital Signature, Key Agreement
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Authority Key Identifier:
                keyid:5B:1D:0E:76:CC:54:B8:BF:AE:46:10:43:6F:79:0B:CA:14:5C:E0:90

    Signature Algorithm: sha256WithRSAEncryption
         bf:41:e2:2f:87:44:25:d8:54:9c:4e:dc:cc:b3:f9:af:5a:a3:
         ...
         ef:0f:90:a6

Installing CA certificate on OpenBMC

The CA certificate can be installed via Redfish Service. The file CA-cert.pem can not be uploaded directly but must be sent embedded in a valid JSON string, which requires \, ", and control characters must be escaped. This means all content is placed in a single string on a single line by encoding the line endings as \n. The command below prepares a whole POST body and puts it into a file named: install_ca.json.

cat << END > install_ca.json
{
  "CertificateString":"$(cat CA-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')",
  "CertificateType": "PEM"
}
END

To install the CA certificate on the OpenBMC server post the content of install_ca.json with this command:

Where ${bmc} should be bmc.example.com. It is convenient to export it as an environment variable.

curl --user root:0penBmc -d @install_ca.json -k -H "Content-Type: application/json" -X POST https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates

Credentials root:0penBmc can be replaced with any system user name and password of your choice but with proper access rights to resources used here.

After successful certificate installation you should get positive HTTP response and a new certificate should be available under this resource collection.

curl --user root:0penBmc -k https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates

An auto-generated self-signed server certificate is already present on OpenBMC by default. To use the certificate signed by our CA it must be replaced. Additionally we must upload to OpenBMC the private key that was used to sign the server certificate. A proper message mody can be prepared the with this command:

cat << END > replace_cert.json
{
  "CertificateString":"$(cat server-key.pem server-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')",
   "CertificateUri":
   {
      "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1"
   },
  "CertificateType": "PEM"
}
END

To replace the server certificate on the OpenBMC server post the content of replace_cert.json with this command:

curl --user root:0penBmc -d @replace_cert.json -k -H "Content-Type: application/json" -X POST https://${bmc}/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/

Enable TLS authentication

To check current state of the TLS authentication method use this command:

curl --user root:0penBmc -k https://${bmc}/redfish/v1/AccountService

and verify that the attribute Oem->OpenBMC->AuthMethods->TLS is set to true.

To enable TLS authentication use this command:

curl --user root:0penBmc  -k -X PATCH -H "Content-Type: application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": true} } } }' https://${bmc}/redfish/v1/AccountService

To disable TLS authentication use this command:

curl --user root:0penBmc  -k -X PATCH -H "Content-Type: application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": false} } } }' https://${bmc}/redfish/v1/AccountService

Other authentication methods like basic authentication can be enabled or disabled as well using the same mechanism. All supported authentication methods are available under attribute Oem->OpenBMC->AuthMethods of the /redfish/v1/AccountService resource.

Using TLS to access OpenBMC resources

If TLS is enabled, valid CA certificate was uploaded and the server certificate was replaced it should be possible to execute curl requests using only client certificate, key, and CA like below.

curl --cert client-cert.pem --key client-key.pem -vvv --cacert CA-cert.pem https://${bmc}/redfish/v1/SessionService/Sessions

Common mistakes during TLS configuration

  • Invalid date and time on OpenBMC,

  • Testing Redfish resources, like https://${bmc}/redfish/v1 which are always available without any authentication will always result with success, even when TLS is disabled or certificates are invalid.

  • Certificates do not meet the requirements. See paragraphs Verify certificates.

  • Attempting to load the same certificate twice will end up with an error.

  • Not having phosphor-bmcweb-cert-config in the build.