1*** Settings ***
2Documentation    Test certificate in OpenBMC.
3
4Resource         ../../lib/resource.robot
5Resource         ../../lib/bmc_redfish_resource.robot
6Resource         ../../lib/openbmc_ffdc.robot
7Resource         ../../lib/certificate_utils.robot
8Library          String
9
10Force Tags       Certificate_Test
11
12Suite Setup      Suite Setup Execution
13Test Teardown    Test Teardown Execution
14
15
16*** Variables ***
17
18${invalid_value}  abc
19${ROOT_CA_FILE_PATH}  /etc/ssl/certs/authority/*
20
21
22** Test Cases **
23
24Verify Server Certificate Replace
25    [Documentation]  Verify server certificate replace.
26    [Tags]  Verify_Server_Certificate_Replace
27    [Template]  Replace Certificate Via Redfish
28
29    # cert_type  cert_format                         expected_status
30    Server       Valid Certificate Valid Privatekey  ok
31    Server       Empty Certificate Valid Privatekey  error
32    Server       Valid Certificate Empty Privatekey  error
33    Server       Empty Certificate Empty Privatekey  error
34
35
36Verify Client Certificate Replace
37    [Documentation]  Verify client certificate replace.
38    [Tags]  Verify_Client_Certificate_Replace
39    [Template]  Replace Certificate Via Redfish
40
41    # cert_type  cert_format                         expected_status
42    Client       Valid Certificate Valid Privatekey  ok
43    Client       Empty Certificate Valid Privatekey  error
44    Client       Valid Certificate Empty Privatekey  error
45    Client       Empty Certificate Empty Privatekey  error
46
47
48Verify CA Certificate Replace
49    [Documentation]  Verify CA certificate replace.
50    [Tags]  Verify_CA_Certificate_Replace
51    [Template]  Replace Certificate Via Redfish
52
53    # cert_type  cert_format        expected_status
54    CA           Valid Certificate  ok
55    CA           Empty Certificate  error
56
57
58Verify Client Certificate Install
59    [Documentation]  Verify client certificate install.
60    [Tags]  Verify_Client_Certificate_Install
61    [Template]  Install And Verify Certificate Via Redfish
62
63    # cert_type  cert_format                         expected_status
64    Client       Valid Certificate Valid Privatekey  ok
65    Client       Empty Certificate Valid Privatekey  error
66    Client       Valid Certificate Empty Privatekey  error
67    Client       Empty Certificate Empty Privatekey  error
68
69
70Verify CA Certificate Install
71    [Documentation]  Verify CA certificate install.
72    [Tags]  Verify_CA_Certificate_Install
73    [Template]  Install And Verify Certificate Via Redfish
74
75    # cert_type  cert_format        expected_status
76    CA           Valid Certificate  ok
77    CA           Empty Certificate  error
78
79
80Verify Maximum CA Certificate Install
81    [Documentation]  Verify maximum CA certificate install.
82    [Tags]  Verify_Maximum_CA_Certificate_Install
83    [Teardown]  Run Keywords  FFDC On Test Case Fail  AND  Delete All CA Certificate Via Redfish
84
85    # Get CA certificate count from BMC.
86    redfish.Login
87    ${cert_list}=  Redfish_Utils.Get Member List  /redfish/v1/Managers/bmc/Truststore/Certificates
88    ${cert_count}=  Get Length  ${cert_list}
89
90    # Install CA certificate to reach maximum count of 10.
91    FOR  ${INDEX}  IN RANGE  ${cert_count}  10
92      Install And Verify Certificate Via Redfish  CA  Valid Certificate  ok  ${FALSE}
93      ${cert_count}=  Evaluate  ${cert_count} + 1
94    END
95
96    # Verify error while installing 11th CA certificate.
97    Install And Verify Certificate Via Redfish  CA  Valid Certificate  error  ${FALSE}
98
99
100Verify Error While Uploding Same CA Certificate
101    [Documentation]  Verify error while uploading same CA certificate two times.
102    [Tags]  Verify_Error_While_Uploding_Same_CA_Certificate
103
104    # Create certificate file for uploading.
105    ${cert_file_path}=  Generate Certificate File Via Openssl  Valid Certificate  365
106    ${bytes}=  OperatingSystem.Get Binary File  ${cert_file_path}
107    ${file_data}=  Decode Bytes To String  ${bytes}  UTF-8
108
109    # Install CA certificate.
110    Install Certificate File On BMC  ${REDFISH_CA_CERTIFICATE_URI}  ok  data=${file_data}
111
112    # Adding delay after certificate installation.
113    Sleep  30s
114
115    # Check error while uploading same certificate.
116    Install Certificate File On BMC  ${REDFISH_CA_CERTIFICATE_URI}  error  data=${file_data}
117
118
119Verify Server Certificate View Via Openssl
120    [Documentation]  Verify server certificate via openssl command.
121    [Tags]  Verify_Server_Certificate_View_Via_Openssl
122
123    redfish.Login
124
125    ${cert_file_path}=  Generate Certificate File Via Openssl  Valid Certificate Valid Privatekey
126    ${bytes}=  OperatingSystem.Get Binary File  ${cert_file_path}
127    ${file_data}=  Decode Bytes To String  ${bytes}  UTF-8
128
129    ${certificate_dict}=  Create Dictionary
130    ...  @odata.id=/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1
131    ${payload}=  Create Dictionary  CertificateString=${file_data}
132    ...  CertificateType=PEM  CertificateUri=${certificate_dict}
133
134    ${resp}=  redfish.Post  /redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate
135    ...  body=${payload}
136
137    Wait Until Keyword Succeeds  2 mins  15 secs  Verify Certificate Visible Via OpenSSL  ${cert_file_path}
138
139
140Verify CSR Generation For Server Certificate
141    [Documentation]  Verify CSR generation for server certificate.
142    [Tags]  Verify_CSR_Generation_For_Server_Certificate
143    [Template]  Generate CSR Via Redfish
144
145    # csr_type  key_pair_algorithm  key_bit_length  key_curv_id  expected_status
146    Server      RSA                 ${2048}         ${EMPTY}     ok
147    Server      EC                  ${EMPTY}        prime256v1   ok
148    Server      EC                  ${EMPTY}        secp521r1    ok
149    Server      EC                  ${EMPTY}        secp384r1    ok
150
151
152Verify CSR Generation For Client Certificate
153    [Documentation]  Verify CSR generation for client certificate.
154    [Tags]  Verify_CSR_Generation_For_Client_Certificate
155    [Template]  Generate CSR Via Redfish
156
157    # csr_type  key_pair_algorithm  key_bit_length  key_curv_id  expected_status
158    Client      RSA                 ${2048}         ${EMPTY}     ok
159    Client      EC                  ${EMPTY}        prime256v1   ok
160    Client      EC                  ${EMPTY}        secp521r1    ok
161    Client      EC                  ${EMPTY}        secp384r1    ok
162
163
164Verify CSR Generation For Server Certificate With Invalid Value
165    [Documentation]  Verify error while generating CSR for server certificate with invalid value.
166    [Tags]  Verify_CSR_Generation_For_Server_Certificate_With_Invalid_Value
167    [Template]  Generate CSR Via Redfish
168
169    # csr_type  key_pair_algorithm  key_bit_length    key_curv_id       expected_status
170    Server      ${invalid_value}    ${2048}           prime256v1        error
171    Server      RAS                 ${invalid_value}  ${EMPTY}          error
172    Server      EC                  ${EMPTY}          ${invalid_value}  error
173
174
175Verify CSR Generation For Client Certificate With Invalid Value
176    [Documentation]  Verify error while generating CSR for client certificate with invalid value.
177    [Tags]  Verify_CSR_Generation_For_Client_Certificate_With_Invalid_Value
178    [Template]  Generate CSR Via Redfish
179
180    Client      ${invalid_value}    ${2048}           prime256v1        error
181    Client      RSA                 ${invalid_value}  ${EMPTY}          error
182    Client      EC                  ${EMPTY}          ${invalid_value}  error
183
184
185*** Keywords ***
186
187Install And Verify Certificate Via Redfish
188    [Documentation]  Install and verify certificate using Redfish.
189    [Arguments]  ${cert_type}  ${cert_format}  ${expected_status}  ${delete_cert}=${True}
190
191    # Description of argument(s):
192    # cert_type           Certificate type (e.g. "Client" or "CA").
193    # cert_format         Certificate file format
194    #                     (e.g. "Valid_Certificate_Valid_Privatekey").
195    # expected_status     Expected status of certificate replace Redfish
196    #                     request (i.e. "ok" or "error").
197    # delete_cert         Certificate will be deleted before installing if this True.
198
199    redfish.Login
200    Run Keyword If  '${cert_type}' == 'CA' and '${delete_cert}' == '${True}'
201    ...  Delete All CA Certificate Via Redfish
202    ...  ELSE IF  '${cert_type}' == 'Client' and '${delete_cert}' == '${True}'
203    ...  Delete Certificate Via BMC CLI  ${cert_type}
204
205    ${time}=  Set Variable If  '${cert_format}' == 'Expired Certificate'  -10  365
206    ${cert_file_path}=  Generate Certificate File Via Openssl  ${cert_format}  ${time}
207    ${bytes}=  OperatingSystem.Get Binary File  ${cert_file_path}
208    ${file_data}=  Decode Bytes To String  ${bytes}  UTF-8
209
210    ${certificate_uri}=  Set Variable If
211    ...  '${cert_type}' == 'Client'  ${REDFISH_LDAP_CERTIFICATE_URI}
212    ...  '${cert_type}' == 'CA'  ${REDFISH_CA_CERTIFICATE_URI}
213
214    ${cert_id}=  Install Certificate File On BMC  ${certificate_uri}  ${expected_status}  data=${file_data}
215    Logging  Installed certificate id: ${cert_id}
216
217    # Adding delay after certificate installation.
218    Sleep  30s
219
220    ${cert_file_content}=  OperatingSystem.Get File  ${cert_file_path}
221    ${bmc_cert_content}=  Run Keyword If  '${expected_status}' == 'ok'  redfish_utils.Get Attribute
222    ...  ${certificate_uri}/${cert_id}  CertificateString
223
224    Run Keyword If  '${expected_status}' == 'ok'  Should Contain  ${cert_file_content}  ${bmc_cert_content}
225    [Return]  ${cert_id}
226
227
228Install Certificate File On BMC
229    [Documentation]  Install certificate file in BMC using POST operation.
230    [Arguments]  ${uri}  ${status}=ok  &{kwargs}
231
232    # Description of argument(s):
233    # uri         URI for installing certificate file via Redfish
234    #             e.g. "/redfish/v1/AccountService/LDAP/Certificates".
235    # status      Expected status of certificate installation via Redfish
236    #             e.g. error, ok.
237    # kwargs      A dictionary of keys/values to be passed directly to
238    #             POST Request.
239
240    Initialize OpenBMC  quiet=${quiet}
241
242    ${headers}=  Create Dictionary  Content-Type=application/octet-stream
243    ...  X-Auth-Token=${XAUTH_TOKEN}
244    Set To Dictionary  ${kwargs}  headers  ${headers}
245
246    ${ret}=  Post Request  openbmc  ${uri}  &{kwargs}
247    ${content_json}=  To JSON  ${ret.content}
248    ${cert_id}=  Set Variable If  '${ret.status_code}' == '${HTTP_OK}'  ${content_json["Id"]}  -1
249
250    Run Keyword If  '${status}' == 'ok'
251    ...  Should Be Equal As Strings  ${ret.status_code}  ${HTTP_OK}
252    ...  ELSE IF  '${status}' == 'error'
253    ...  Should Be Equal As Strings  ${ret.status_code}  ${HTTP_INTERNAL_SERVER_ERROR}
254
255    Delete All Sessions
256
257    [Return]  ${cert_id}
258
259Replace Certificate Via Redfish
260    [Documentation]  Test 'replace certificate' operation in the BMC via Redfish.
261    [Arguments]  ${cert_type}  ${cert_format}  ${expected_status}
262
263    # Description of argument(s):
264    # cert_type           Certificate type (e.g. "Server" or "Client").
265    # cert_format         Certificate file format
266    #                     (e.g. Valid_Certificate_Valid_Privatekey).
267    # expected_status     Expected status of certificate replace Redfish
268    #                     request (i.e. "ok" or "error").
269
270    # Install certificate before replacing client or CA certificate.
271    ${cert_id}=  Run Keyword If  '${cert_type}' == 'Client'
272    ...    Install And Verify Certificate Via Redfish  ${cert_type}  Valid Certificate Valid Privatekey  ok
273    ...  ELSE IF  '${cert_type}' == 'CA'
274    ...    Install And Verify Certificate Via Redfish  ${cert_type}  Valid Certificate  ok
275
276    redfish.Login
277
278    ${time}=  Set Variable If  '${cert_format}' == 'Expired Certificate'  -10  365
279    ${cert_file_path}=  Generate Certificate File Via Openssl  ${cert_format}  ${time}
280
281    ${bytes}=  OperatingSystem.Get Binary File  ${cert_file_path}
282    ${file_data}=  Decode Bytes To String  ${bytes}  UTF-8
283
284    ${certificate_uri}=  Set Variable If
285    ...  '${cert_type}' == 'Server'  ${REDFISH_HTTPS_CERTIFICATE_URI}/1
286    ...  '${cert_type}' == 'Client'  ${REDFISH_LDAP_CERTIFICATE_URI}/1
287    ...  '${cert_type}' == 'CA'  ${REDFISH_CA_CERTIFICATE_URI}/${cert_id}
288
289    ${certificate_dict}=  Create Dictionary  @odata.id=${certificate_uri}
290    ${payload}=  Create Dictionary  CertificateString=${file_data}
291    ...  CertificateType=PEM  CertificateUri=${certificate_dict}
292
293    ${expected_resp}=  Set Variable If  '${expected_status}' == 'ok'  ${HTTP_OK}
294    ...  '${expected_status}' == 'error'  ${HTTP_NOT_FOUND}, ${HTTP_INTERNAL_SERVER_ERROR}
295    ${resp}=  redfish.Post  /redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate
296    ...  body=${payload}  valid_status_codes=[${expected_resp}]
297
298    ${cert_file_content}=  OperatingSystem.Get File  ${cert_file_path}
299    ${bmc_cert_content}=  redfish_utils.Get Attribute  ${certificate_uri}  CertificateString
300
301    Run Keyword If  '${expected_status}' == 'ok'
302    ...    Should Contain  ${cert_file_content}  ${bmc_cert_content}
303    ...  ELSE
304    ...    Should Not Contain  ${cert_file_content}  ${bmc_cert_content}
305
306
307Generate CSR Via Redfish
308    [Documentation]  Generate CSR using Redfish.
309    [Arguments]  ${cert_type}  ${key_pair_algorithm}  ${key_bit_length}  ${key_curv_id}  ${expected_status}
310
311    # Description of argument(s):
312    # cert_type           Certificate type ("Server" or "Client").
313    # key_pair_algorithm  CSR key pair algorithm ("EC" or "RSA")
314    # key_bit_length      CSR key bit length ("2048").
315    # key_curv_id         CSR key curv id ("prime256v1" or "secp521r1" or "secp384r1").
316    # expected_status     Expected status of certificate replace Redfish
317    #                     request ("ok" or "error").
318
319    redfish.Login
320
321    ${certificate_uri}=  Set Variable If
322    ...  '${cert_type}' == 'Server'  ${REDFISH_HTTPS_CERTIFICATE_URI}/
323    ...  '${cert_type}' == 'Client'  ${REDFISH_LDAP_CERTIFICATE_URI}/
324
325    ${certificate_dict}=  Create Dictionary  @odata.id=${certificate_uri}
326    ${payload}=  Create Dictionary  City=Austin  CertificateCollection=${certificate_dict}
327    ...  CommonName=${OPENBMC_HOST}  Country=US  Organization=IBM
328    ...  OrganizationalUnit=ISL  State=AU  KeyBitLength=${key_bit_length}
329    ...  KeyPairAlgorithm=${key_pair_algorithm}  KeyCurveId=${key_curv_id}
330
331    # Remove not applicable field for CSR generation.
332    Run Keyword If  '${key_pair_algorithm}' == 'EC'  Remove From Dictionary  ${payload}  KeyBitLength
333    ...  ELSE IF  '${key_pair_algorithm}' == 'RSA'  Remove From Dictionary  ${payload}  KeyCurveId
334
335    ${expected_resp}=  Set Variable If  '${expected_status}' == 'ok'  ${HTTP_OK}
336    ...  '${expected_status}' == 'error'  ${HTTP_INTERNAL_SERVER_ERROR}, ${HTTP_BAD_REQUEST}
337    ${resp}=  redfish.Post  /redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR
338    ...  body=${payload}  valid_status_codes=[${expected_resp}]
339
340    # Delay added between two CSR generation request.
341    Sleep  5s
342
343
344Delete Certificate Via BMC CLI
345    [Documentation]  Delete certificate via BMC CLI.
346    [Arguments]  ${cert_type}
347
348    # Description of argument(s):
349    # cert_type           Certificate type (e.g. "Client" or "CA").
350
351    ${certificate_file_path}  ${certificate_service}  ${certificate_uri}=
352    ...  Run Keyword If  '${cert_type}' == 'Client'
353    ...    Set Variable  /etc/nslcd/certs/cert.pem  phosphor-certificate-manager@nslcd.service
354    ...    ${REDFISH_LDAP_CERTIFICATE_URI}
355    ...  ELSE IF  '${cert_type}' == 'CA'
356    ...    Set Variable  ${ROOT_CA_FILE_PATH}  phosphor-certificate-manager@authority.service
357    ...    ${REDFISH_CA_CERTIFICATE_URI}
358
359    ${file_status}  ${stderr}  ${rc}=  BMC Execute Command
360    ...  [ -f ${certificate_file_path} ] && echo "Found" || echo "Not Found"
361
362    Return From Keyword If  "${file_status}" != "Found"
363    BMC Execute Command  rm ${certificate_file_path}
364    BMC Execute Command  systemctl restart ${certificate_service}
365    BMC Execute Command  systemctl daemon-reload
366    Wait Until Keyword Succeeds  1 min  10 sec  Redfish.Get  ${certificate_uri}/1
367    ...  valid_status_codes=[${HTTP_NOT_FOUND}, ${HTTP_INTERNAL_SERVER_ERROR}]
368
369
370Delete All CA Certificate Via Redfish
371    [Documentation]  Delete all CA certificate via Redfish.
372
373    ${cert_list}=  Redfish_Utils.Get Member List  /redfish/v1/Managers/bmc/Truststore/Certificates
374    FOR  ${cert}  IN  @{cert_list}
375      Redfish.Delete  ${cert}  valid_status_codes=[${HTTP_NO_CONTENT}]
376    END
377
378
379Suite Setup Execution
380    [Documentation]  Do suite setup tasks.
381
382    # Create certificate sub-directory in current working directory.
383    Create Directory  certificate_dir
384
385
386Test Teardown Execution
387    [Documentation]  Do the post test teardown.
388
389    FFDC On Test Case Fail
390    redfish.Logout
391