1*** Settings ***
2Documentation  Certificate utilities keywords.
3
4Library        OperatingSystem
5Resource       rest_client.robot
6Resource       resource.robot
7
8
9*** Keywords ***
10
11Install Certificate File On BMC
12    [Documentation]  Install certificate file in BMC using POST operation.
13    [Arguments]  ${uri}  ${status}=ok  &{kwargs}
14
15    # Description of argument(s):
16    # uri         URI for installing certificate file via Redfish
17    #             e.g. "/redfish/v1/AccountService/LDAP/Certificates".
18    # status      Expected status of certificate installation via Redfish
19    #             e.g. error, ok.
20    # kwargs      A dictionary of keys/values to be passed directly to
21    #             POST Request.
22
23    Initialize OpenBMC
24
25    ${headers}=  Create Dictionary  Content-Type=application/octet-stream
26    ...  X-Auth-Token=${XAUTH_TOKEN}
27    Set To Dictionary  ${kwargs}  headers  ${headers}
28
29    ${ret}=  Post Request  openbmc  ${uri}  &{kwargs}
30    ${content_json}=  To JSON  ${ret.content}
31    ${cert_id}=  Set Variable If  '${ret.status_code}' == '${HTTP_OK}'  ${content_json["Id"]}  -1
32
33    Run Keyword If  '${status}' == 'ok'
34    ...  Should Be Equal As Strings  ${ret.status_code}  ${HTTP_OK}
35    ...  ELSE IF  '${status}' == 'error'
36    ...  Should Be Equal As Strings  ${ret.status_code}  ${HTTP_INTERNAL_SERVER_ERROR}
37
38    Delete All Sessions
39
40    [Return]  ${cert_id}
41
42
43Get Certificate Content From BMC Via Openssl
44    [Documentation]  Get certificate content from BMC via openssl.
45
46    Check If Openssl Tool Exist
47
48    ${openssl_cmd}=  Catenate
49    ...  timeout 10  openssl s_client -connect ${OPENBMC_HOST}:${HTTPS_PORT} -showcerts
50    ${output}=  Run  ${openssl_cmd}
51
52    ${result}=  Fetch From Left
53    ...  ${output}  -----END CERTIFICATE-----
54    ${result}=  Fetch From Right  ${result}  -----BEGIN CERTIFICATE-----
55    [Return]  ${result}
56
57
58Get Certificate File Content From BMC
59    [Documentation]  Get required certificate file content from BMC.
60    [Arguments]  ${cert_type}=Client
61
62    # Description of argument(s):
63    # cert_type      Certificate type (e.g. "Client" or "CA").
64
65    ${certificate}  ${stderr}  ${rc}=  Run Keyword If  '${cert_type}' == 'Client'
66    ...    BMC Execute Command  cat /etc/nslcd/certs/cert.pem
67
68    [Return]  ${certificate}
69
70
71Generate Certificate File Via Openssl
72    [Documentation]  Create certificate file via openssl with required content
73    ...              and returns its path.
74    [Arguments]  ${cert_format}  ${time}=365  ${cert_dir_name}=certificate_dir
75
76    # Description of argument(s):
77    # cert_format          Certificate file format
78    #                      e.g. Valid_Certificate_Empty_Privatekey.
79    # time                 Number of days to certify the certificate for.
80    # cert_dir_name        The name of the sub-directory where the certificate
81    #                      is stored.
82
83    Check If Openssl Tool Exist
84
85    ${openssl_cmd}=  Catenate  openssl req -x509 -sha256 -newkey rsa:2048
86    ...  ${SPACE}-nodes -days ${time}
87    ...  ${SPACE}-keyout ${cert_dir_name}/cert.pem -out ${cert_dir_name}/cert.pem
88    ...  ${SPACE}-subj "/O=XYZ Corporation /CN=www.xyz.com"
89
90    ${rc}  ${output}=  Run And Return RC and Output  ${openssl_cmd}
91    Should Be Equal  ${rc}  ${0}  msg=${output}
92    OperatingSystem.File Should Exist
93    ...  ${EXECDIR}${/}${cert_dir_name}${/}cert.pem
94
95    ${file_content}=  OperatingSystem.Get File
96    ...  ${EXECDIR}${/}${cert_dir_name}${/}cert.pem
97    ${result}=  Fetch From Left  ${file_content}  -----END CERTIFICATE-----
98    ${cert_content}=  Fetch From Right  ${result}  -----BEGIN CERTIFICATE-----
99
100    ${result}=  Fetch From Left  ${file_content}  -----END PRIVATE KEY-----
101    ${private_key_content}=  Fetch From Right  ${result}  -----BEGIN PRIVATE KEY-----
102
103    ${cert_data}=
104    ...  Run Keyword if  '${cert_format}' == 'Valid Certificate Valid Privatekey'
105    ...  OperatingSystem.Get File  ${EXECDIR}${/}${cert_dir_name}${/}cert.pem
106    ...  ELSE IF  '${cert_format}' == 'Empty Certificate Valid Privatekey'
107    ...  Remove String  ${file_content}  ${cert_content}
108    ...  ELSE IF  '${cert_format}' == 'Valid Certificate Empty Privatekey'
109    ...  Remove String  ${file_content}  ${private_key_content}
110    ...  ELSE IF  '${cert_format}' == 'Empty Certificate Empty Privatekey'
111    ...  Remove String  ${file_content}  ${cert_content}  ${private_key_content}
112    ...  ELSE IF  '${cert_format}' == 'Expired Certificate' or '${cert_format}' == 'Not Yet Valid Certificate'
113    ...  OperatingSystem.Get File  ${EXECDIR}${/}${cert_dir_name}${/}cert.pem
114    ...  ELSE IF  '${cert_format}' == 'Valid Certificate'
115    ...  Remove String  ${file_content}  ${private_key_content}
116    ...  -----BEGIN PRIVATE KEY-----  -----END PRIVATE KEY-----
117    ...  ELSE IF  '${cert_format}' == 'Empty Certificate'
118    ...  Remove String  ${file_content}  ${cert_content}
119    ...  ${private_key_content}  -----BEGIN PRIVATE KEY-----
120    ...  -----END PRIVATE KEY-----
121
122    ${random_name}=  Generate Random String  8
123    ${cert_name}=  Catenate  SEPARATOR=  ${random_name}  .pem
124    Create File  ${cert_dir_name}/${cert_name}  ${cert_data}
125
126    [Return]  ${EXECDIR}${/}${cert_dir_name}${/}${cert_name}
127
128
129Get Certificate Content From File
130    [Documentation]  Get certificate content from certificate file.
131    [Arguments]  ${cert_file_path}
132
133    # Description of argument(s):
134    # cert_file_path  Downloaded certificate file path.
135
136    ${file_content}=  OperatingSystem.Get File  ${cert_file_path}
137    ${result}=  Fetch From Left  ${file_content}  -----END CERTIFICATE-----
138    ${result}=  Fetch From Right  ${result}  -----BEGIN CERTIFICATE-----
139    [Return]  ${result}
140
141
142Check If Openssl Tool Exist
143    [Documentation]  Check if openssl tool installed or not.
144
145    ${rc}  ${output}=  Run And Return RC and Output  which openssl
146    Should Not Be Empty  ${output}  msg=Openssl tool not installed.
147
148
149Verify Certificate Visible Via OpenSSL
150    [Documentation]  Checks if given certificate is visible via openssl's showcert command.
151    [Arguments]  ${cert_file_path}
152
153    # Description of argument(s):
154    # cert_file_path           Certificate file path.
155
156    ${cert_file_content}=  OperatingSystem.Get File  ${cert_file_path}
157    ${openssl_cert_content}=  Get Certificate Content From BMC Via Openssl
158    Should Contain  ${cert_file_content}  ${openssl_cert_content}
159
160
161Delete All CA Certificate Via Redfish
162    [Documentation]  Delete all CA certificate via Redfish.
163    ${cert_list}=  Redfish_Utils.Get Member List  /redfish/v1/Managers/bmc/Truststore/Certificates
164    FOR  ${cert}  IN  @{cert_list}
165      Redfish.Delete  ${cert}  valid_status_codes=[${HTTP_NO_CONTENT}]
166    END
167
168
169Delete Certificate Via BMC CLI
170    [Documentation]  Delete certificate via BMC CLI.
171    [Arguments]  ${cert_type}
172
173    # Description of argument(s):
174    # cert_type           Certificate type (e.g. "Client" or "CA").
175
176    ${certificate_file_path}  ${certificate_service}  ${certificate_uri}=
177    ...  Run Keyword If  '${cert_type}' == 'Client'
178    ...    Set Variable  /etc/nslcd/certs/cert.pem  phosphor-certificate-manager@nslcd.service
179    ...    ${REDFISH_LDAP_CERTIFICATE_URI}
180    ...  ELSE IF  '${cert_type}' == 'CA'
181    ...    Set Variable  ${ROOT_CA_FILE_PATH}  phosphor-certificate-manager@authority.service
182    ...    ${REDFISH_CA_CERTIFICATE_URI}
183
184    ${file_status}  ${stderr}  ${rc}=  BMC Execute Command
185    ...  [ -f ${certificate_file_path} ] && echo "Found" || echo "Not Found"
186
187    Return From Keyword If  "${file_status}" != "Found"
188    BMC Execute Command  rm ${certificate_file_path}
189    BMC Execute Command  systemctl restart ${certificate_service}
190    BMC Execute Command  systemctl daemon-reload
191    Wait Until Keyword Succeeds  1 min  10 sec  Redfish.Get  ${certificate_uri}/1
192    ...  valid_status_codes=[${HTTP_NOT_FOUND}, ${HTTP_INTERNAL_SERVER_ERROR}]
193