1# How to configure the server TLS certificates for authentication
2
3Author: Zbigniew Kurzynski <zbigniew.kurzynski@intel.com>
4
5Created: May 8, 2020
6
7Related documents:
8
9- [Redfish TLS User Authentication](https://github.com/openbmc/docs/blob/master/designs/redfish-tls-user-authentication.md)
10
11## Introduction
12
13With help of this guidebook you should be able to create both client and server
14certificates signed by a CA that can be used to authenticate user requests to an
15OpenBMC server. You will also learn how to enable and test the OpenBMC TLS
16authentication.
17
18## Certificates
19
20For a certificate to be marked as valid, it (and every certificate in the chain)
21has to meet these conditions:
22
23- `KeyUsage` contains required purpose `digitalSignature` and `keyAgreement`
24  (see rfc 3280 4.2.1.3)
25- `ExtendedKeyUsage` contains required purpose `clientAuth` for client
26  certificate and `serverAuth` for server certificate (see rfc 3280 4.2.1.13)
27- public key meets minimal bit length requirement
28- certificate has to be in its validity period
29- `notBefore` and `notAfter` fields have to contain valid time
30- has to be properly signed by certificate authority
31- certificate is well-formed according to X.509
32- issuer name has to match CA's subject name for client certificate
33- issuer name has to match the fully qualified domain name of your OpenBMC host
34
35If you already have certificates you can skip to
36[Enable TLS authentication ](#Enable-TLS-authentication) or go to
37[Verify certificates](#Verify-certificates) and check if they meet the above
38requirements.
39
40### Prepare configuration files
41
42To generate certificates with required parameters some modification must be made
43to the default openssl configuration file.
44
45First create a new folder named `ca` and create a configuration file using the
46default configuration as a template (we do not want to change the original one).
47The location of the configuration file may vary depending on the operating
48system. For Ubuntu it is usually `/usr/lib/ssl/openssl.cnf`, but can also can be
49at `/etc/ssl/openssl.cnf`. For Cygwin it might be
50`/etc/defaults/etc/pki/tls/openssl.cnf` or `/etc/pki/tls/openssl.cnf`.
51
52```
53mkdir ~/ca
54cd ~/ca
55cp /usr/lib/ssl/openssl.cnf openssl-client.cnf
56```
57
58Then open the client `~/ca/openssl-client.cnf` file in your favorite editor, for
59example `vi`.
60
61```
62vi ~/ca/openssl-client.cnf
63```
64
65Find the sections listed below and add or choose the presented values.
66
67```
68[ req ]
69req_extensions = v3_req
70
71[ usr_cert ]
72extendedKeyUsage = clientAuth
73
74[ v3_req ]
75extendedKeyUsage = clientAuth
76keyUsage = digitalSignature, keyAgreement
77```
78
79Now create a server configuration `openssl-server.cnf` by copying the client
80file
81
82```
83cp ~/ca/openssl-client.cnf openssl-server.cnf
84```
85
86and changing values presented in the sections listed below.
87
88```
89[ usr_cert ]
90extendedKeyUsage = serverAuth
91
92[ v3_req ]
93extendedKeyUsage = serverAuth
94```
95
96Create two additional configuration files `myext-client.cnf` and
97`myext-server.cnf` for the client and server certificates respectively. Without
98these files no extensions are added to the certificate.
99
100```
101cat << END > myext-client.cnf
102[ my_ext_section ]
103keyUsage = digitalSignature, keyAgreement
104extendedKeyUsage = clientAuth
105authorityKeyIdentifier = keyid
106END
107```
108
109```
110cat << END > myext-server.cnf
111[ my_ext_section ]
112keyUsage = digitalSignature, keyAgreement
113extendedKeyUsage = serverAuth
114authorityKeyIdentifier = keyid
115END
116```
117
118### Create a new CA certificate
119
120First we need to create a private key to sign the CA certificate.
121
122```
123openssl genrsa -out CA-key.pem 2048
124```
125
126Now we can create a CA certificate, using the previously generated key. You will
127be prompted for information which will be incorporated into the certificate,
128such as Country, City, Company Name, etc.
129
130```
131openssl req -new -config openssl-client.cnf -key CA-key.pem -x509 -days 1000 -out CA-cert.pem
132```
133
134### Create client certificate signed by given CA certificate
135
136To create a client certificate, a signing request must be created first. For
137this another private key will be needed.
138
139Generate a new key that will be used to sign the certificate signing request:
140
141```
142openssl genrsa -out client-key.pem 2048
143```
144
145Generate a certificate signing request.
146
147You will be prompted for the same information as during CA generation, but
148provide **the OpenBMC system user name** for the `CommonName` attribute of this
149certificate. In this example, use **root**.
150
151```
152openssl req -new -config openssl-client.cnf -key client-key.pem -out signingReqClient.csr
153```
154
155Sign the certificate using your `CA-cert.pem` certificate with following
156command:
157
158```
159openssl 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
160```
161
162The file `client-cert.pem` now contains a signed client certificate.
163
164### Create server certificate signed by given CA certificate
165
166For convenience we will use the same CA generated in paragraph
167[Create a new CA certificate](#Create-a-new-CA-certificate), although a
168different one could be used.
169
170Generate a new key that will be used to sign the server certificate signing
171request:
172
173```
174openssl genrsa -out server-key.pem 2048
175```
176
177Generate a certificate signing request. You will be prompted for the same
178information as during CA generation, but provide **the fully qualified domain
179name of your OpenBMC server** for the `CommonName` attribute of this
180certificate. In this example it will be `bmc.example.com`. A wildcard can be
181used to protect multiple host, for example a certificate configured for
182`*.example.com` will secure www.example.com, as well as mail.example.com,
183blog.example.com, and others.
184
185```
186openssl req -new -config openssl-server.cnf -key server-key.pem -out signingReqServer.csr
187```
188
189Sign the certificate using your `CA-cert.pem` certificate with following
190command:
191
192```
193openssl 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
194```
195
196The file `server-cert.pem` now contains a signed server certificate.
197
198### Verify certificates
199
200To verify the signing request and both certificates you can use following
201commands.
202
203```
204openssl x509 -in CA-cert.pem -text -noout
205openssl x509 -in client-cert.pem -text -noout
206openssl x509 -in server-cert.pem -text -noout
207openssl req -in signingReqClient.csr -noout -text
208openssl req -in signingReqServer.csr -noout -text
209```
210
211Below are example listings that you can compare with your results. Pay special
212attention to attributes like:
213
214- Validity in both certificates,
215- `Issuer` in `client-cert.pem`, it must match to `Subject` in `CA-cert.pem`,
216- Section _X509v3 extensions_ in `client-cert.pem` it should contain proper
217  values,
218- `Public-Key` length, it cannot be less than 2048 bits.
219- `Subject` CN in `client-cert.pem`, it should match existing OpemBMC user name.
220  In this example it is **root**.
221- `Subject` CN in `server-cert.pem`, it should match OpemBMC host name. In this
222  example it is **bmc.example.com **. (see rfc 3280 4.2.1.11 for name
223  constraints)
224
225Below are fragments of generated certificates that you can compare with.
226
227```
228CA-cert.pem
229    Data:
230        Version: 3 (0x2)
231        Serial Number: 16242916899984461675 (0xe16a6edca3c34f6b)
232    Signature Algorithm: sha256WithRSAEncryption
233        Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
234        Validity
235            Not Before: May 11 11:40:48 2020 GMT
236            Not After : Feb  5 11:40:48 2023 GMT
237        Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
238        Subject Public Key Info:
239            Public Key Algorithm: rsaEncryption
240                Public-Key: (2048 bit)
241                Modulus:
242                    00:d4:24:c1:1d:ac:85:8c:5b:42:e4:f8:a8:d8:7c:
243                    ...
244                    55:83:8b:aa:ac:ac:6e:e3:01:2b:ce:f7:ee:87:21:
245                    f9:2b
246                Exponent: 65537 (0x10001)
247        X509v3 extensions:
248            X509v3 Subject Key Identifier:
249                ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
250            X509v3 Authority Key Identifier:
251                keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
252
253            X509v3 Basic Constraints:
254                CA:TRUE
255    Signature Algorithm: sha256WithRSAEncryption
256         cc:8b:61:6a:55:60:2b:26:55:9f:a6:0c:42:b0:47:d4:ec:e0:
257         ...
258         45:47:91:62:10:bd:3e:a8:da:98:33:65:cc:11:23:95:06:1b:
259         ee:d3:78:84
260```
261
262```
263client-cert.pem
264    Data:
265        Version: 3 (0x2)
266        Serial Number: 10150871893861973895 (0x8cdf2434b223bf87)
267    Signature Algorithm: sha256WithRSAEncryption
268        Issuer: C=US, ST=California, L=San Francisco, O=Intel, CN=Test CA
269        Validity
270            Not Before: May 11 11:42:58 2020 GMT
271            Not After : May 11 11:42:58 2021 GMT
272        Subject: C=US, ST=California, L=San Francisco, O=Intel, CN=root
273        Subject Public Key Info:
274            Public Key Algorithm: rsaEncryption
275                Public-Key: (2048 bit)
276                Modulus:
277                    00:cf:d6:d0:a2:09:62:df:e9:a9:b1:e1:3d:7f:2f:
278                    ...
279                    30:7b:48:dc:c5:2c:3f:a9:c0:d1:b6:04:d4:1a:c8:
280                    8a:51
281                Exponent: 65537 (0x10001)
282        X509v3 extensions:
283            X509v3 Key Usage:
284                Digital Signature, Key Agreement
285            X509v3 Extended Key Usage:
286                TLS Web Client Authentication
287            X509v3 Authority Key Identifier:
288                keyid:ED:FF:80:A7:F8:DA:99:7F:94:35:95:F0:92:74:1A:55:CD:DF:BA:FE
289
290    Signature Algorithm: sha256WithRSAEncryption
291         7f:a4:57:f5:97:48:2a:c4:8e:d3:ef:d8:a1:c9:65:1b:20:fd:
292         ...
293         25:cb:5e:0a:37:fb:a1:ab:b0:c4:62:fe:51:d3:1c:1b:fb:11:
294         56:57:4c:6a
295```
296
297```
298server-cert.pem
299    Data:
300        Version: 3 (0x2)
301        Serial Number: 10622848005881387807 (0x936beffaa586db1f)
302    Signature Algorithm: sha256WithRSAEncryption
303        Issuer: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com
304        Validity
305            Not Before: May 22 13:46:02 2020 GMT
306            Not After : May 22 13:46:02 2021 GMT
307        Subject: C=US, ST=z, L=z, O=z, OU=z, CN=bmc.example.com
308        Subject Public Key Info:
309            Public Key Algorithm: rsaEncryption
310                Public-Key: (2048 bit)
311                Modulus:
312                    00:d9:34:9c:da:83:c6:eb:af:8f:e8:11:56:2a:59:
313                    ...
314                    92:60:09:fc:f9:66:82:d0:27:03:44:2f:9d:6d:c0:
315                    a5:6d
316                Exponent: 65537 (0x10001)
317        X509v3 extensions:
318            X509v3 Key Usage:
319                Digital Signature, Key Agreement
320            X509v3 Extended Key Usage:
321                TLS Web Server Authentication
322            X509v3 Authority Key Identifier:
323                keyid:5B:1D:0E:76:CC:54:B8:BF:AE:46:10:43:6F:79:0B:CA:14:5C:E0:90
324
325    Signature Algorithm: sha256WithRSAEncryption
326         bf:41:e2:2f:87:44:25:d8:54:9c:4e:dc:cc:b3:f9:af:5a:a3:
327         ...
328         ef:0f:90:a6
329
330```
331
332## Installing CA certificate on OpenBMC
333
334The CA certificate can be installed via Redfish Service. The file `CA-cert.pem`
335can not be uploaded directly but must be sent embedded in a valid JSON string,
336which requires `\`, `"`, and control characters must be escaped. This means all
337content is placed in a single string on a single line by encoding the line
338endings as `\n`. The command below prepares a whole POST body and puts it into a
339file named: `install_ca.json`.
340
341```
342cat << END > install_ca.json
343{
344  "CertificateString":"$(cat CA-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')",
345  "CertificateType": "PEM"
346}
347END
348```
349
350To install the CA certificate on the OpenBMC server post the content of
351`install_ca.json` with this command:
352
353Where `${bmc}` should be `bmc.example.com`. It is convenient to export it as an
354environment variable.
355
356```
357curl --user root:0penBmc -d @install_ca.json -k -X POST https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates
358
359```
360
361Credentials `root:0penBmc` can be replaced with any system user name and
362password of your choice but with proper access rights to resources used here.
363
364After successful certificate installation you should get positive HTTP response
365and a new certificate should be available under this resource collection.
366
367```
368curl --user root:0penBmc -k https://${bmc}/redfish/v1/Managers/bmc/Truststore/Certificates
369
370```
371
372An auto-generated self-signed server certificate is already present on OpenBMC
373by default. To use the certificate signed by our CA it must be replaced.
374Additionally we must upload to OpenBMC the private key that was used to sign the
375server certificate. A proper message mody can be prepared the with this command:
376
377```
378cat << END > replace_cert.json
379{
380  "CertificateString":"$(cat server-key.pem server-cert.pem | sed -n -e '1h;1!H;${x;s/\n/\\n/g;p;}')",
381   "CertificateUri":
382   {
383      "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1"
384   },
385  "CertificateType": "PEM"
386}
387END
388```
389
390To replace the server certificate on the OpenBMC server post the content of
391`replace_cert.json` with this command:
392
393```
394curl --user root:0penBmc -d @replace_cert.json -k -X POST https://${bmc}/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate/
395
396```
397
398## Enable TLS authentication
399
400To check current state of the TLS authentication method use this command:
401
402```
403curl --user root:0penBmc -k https://${bmc}/redfish/v1/AccountService
404```
405
406and verify that the attribute `Oem->OpenBMC->AuthMethods->TLS` is set to true.
407
408To enable TLS authentication use this command:
409
410```
411curl --user root:0penBmc  -k -X PATCH -H "ContentType:application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": true} } } }' https://${bmc}/redfish/v1/AccountService
412```
413
414To disable TLS authentication use this command:
415
416```
417curl --user root:0penBmc  -k -X PATCH -H "ContentType:application/json" --data '{"Oem": {"OpenBMC": {"AuthMethods": { "TLS": false} } } }' https://${bmc}/redfish/v1/AccountService
418```
419
420Other authentication methods like basic authentication can be enabled or
421disabled as well using the same mechanism. All supported authentication methods
422are available under attribute `Oem->OpenBMC->AuthMethods` of the
423`/redfish/v1/AccountService` resource.
424
425## Using TLS to access OpenBMC resources
426
427If TLS is enabled, valid CA certificate was uploaded and the server certificate
428was replaced it should be possible to execute curl requests using only client
429certificate, key, and CA like below.
430
431```
432curl --cert client-cert.pem --key client-key.pem -vvv --cacert CA-cert.pem https://${bmc}/redfish/v1/SessionService/Sessions
433```
434
435## Common mistakes during TLS configuration
436
437- Invalid date and time on OpenBMC,
438
439- Testing Redfish resources, like `https://${bmc}/redfish/v1` which are always
440  available without any authentication will always result with success, even
441  when TLS is disabled or certificates are invalid.
442
443- Certificates do not meet the requirements. See paragraphs
444  [Verify certificates](#Verify-certificates).
445
446- Attempting to load the same certificate twice will end up with an error.
447
448- Not having phosphor-bmcweb-cert-config in the build.
449