Enable basic framework to test certificate upload

Also added test cases to test certificate install with
different format.

Resolves openbmc/openbmc-test-automation#1460

Change-Id: I0047242c2783e589c3095e829f43313e8ad82d81
Signed-off-by: Rahul Maheshwari <rahulmaheshwari@in.ibm.com>
diff --git a/data/variables.py b/data/variables.py
old mode 100644
new mode 100755
index 105f9fb..d4d84ac
--- a/data/variables.py
+++ b/data/variables.py
@@ -144,6 +144,11 @@
 # rsyslog variables.
 REMOTE_LOGGING_URI = OPENBMC_BASE_URI + 'logging/config/remote/'
 
+# Certificate variables.
+SERVER_CERTIFICATE_URI = OPENBMC_BASE_URI + 'certs/server/https'
+CLIENT_CERTIFICATE_URI = OPENBMC_BASE_URI + 'certs/client/ldap'
+
+
 '''
   QEMU HTTPS variable:
 
diff --git a/lib/certificate_utils.robot b/lib/certificate_utils.robot
new file mode 100755
index 0000000..4e0a83c
--- /dev/null
+++ b/lib/certificate_utils.robot
@@ -0,0 +1,134 @@
+*** Settings ***
+Documentation  Certificate utilities keywords.
+
+Library        OperatingSystem
+Resource       rest_client.robot
+Resource       resource.txt
+
+
+*** Keywords ***
+
+Install Certificate File On BMC
+    [Documentation]  Install certificate file in BMC using REST PUT operation.
+    [Arguments]  ${uri}  ${status}=ok  ${quiet}=${1}  &{kwargs}
+
+    # Description of argument(s):
+    # uri         URI for installing certificate file via REST
+    #             e.g. "/xyz/openbmc_project/certs/server/https".
+    # status      Expected status of certificate installation via REST
+    #             e.g. error, ok.
+    # quiet       If enabled, turns off logging to console.
+    # kwargs      A dictionary of keys/values to be passed directly to
+    #             PUT Request.
+
+    Initialize OpenBMC  quiet=${quiet}
+
+    ${headers}=  Create Dictionary  Content-Type=application/octet-stream
+    Set To Dictionary  ${kwargs}  headers  ${headers}
+
+    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Put
+    ...  base_uri=${uri}  args=&{kwargs}
+
+    ${ret}=  Put Request  openbmc  ${uri}  &{kwargs}
+    Run Keyword If  '${quiet}' == '${0}'  Log Response  ${ret}
+
+    Run Keyword If  '${status}' == 'ok'
+    ...  Should Be Equal As Strings  ${ret.status_code}  ${HTTP_OK}
+    ...  ELSE IF  '${status}' == 'error'
+    ...  Should Be Equal As Strings  ${ret.status_code}  ${HTTP_BAD_REQUEST}
+
+    Delete All Sessions
+
+
+Get Certificate Content From BMC Via Openssl
+    [Documentation]  Get certificate content from BMC via openssl.
+
+    Check If Openssl Tool Exist
+
+    ${openssl_cmd}=  Catenate
+    ...  openssl s_client -connect ${OPENBMC_HOST}:443 -showcerts
+    ${rc}  ${output}=  Run And Return RC and Output  ${openssl_cmd}
+    Should Be Equal  ${rc}  ${0}  msg=${output}
+
+    ${result}=  Fetch From Left
+    ...  ${output}  -----END CERTIFICATE-----
+    ${result}=  Fetch From Right  ${result}  -----BEGIN CERTIFICATE-----
+    [Return]  ${result}
+
+
+Get Client Certificate File Content From BMC
+    [Documentation]  Get client certificate file content from BMC.
+
+    ${certificate}  ${stderr}  ${rc}=  BMC Execute Command
+    ...  cat /etc/nslcd/certs/cert.pem
+    Should Be Equal  ${rc}  ${0}  msg=${stderr}
+
+    [Return]  ${certificate}
+
+
+Generate Certificate File Via Openssl
+    [Documentation]  Create certificate file via openssl with required content
+    ...              and returns its path.
+    [Arguments]  ${cert_format}  ${time}=365
+
+    # Description of argument(s):
+    # cert_format          Certificate file format
+    #                      e.g. Valid_Certificate_Empty_Privatekey.
+    # time                 Number of days to certify the certificate for.
+
+    Check If Openssl Tool Exist
+
+    ${openssl_cmd}=  Catenate  openssl req -x509 -sha256 -newkey rsa:2048
+    ...  ${SPACE}-nodes -days ${time}
+    ...  ${SPACE}-keyout cert.pem -out cert.pem
+    ...  ${SPACE}-subj "/O=XYZ Corporation /CN=www.xyz.com"
+
+    ${rc}  ${output}=  Run And Return RC and Output  ${openssl_cmd}
+    Should Be Equal  ${rc}  ${0}  msg=${output}
+    OperatingSystem.File Should Exist  ${EXECDIR}${/}cert.pem
+
+    ${file_content}=  OperatingSystem.Get File  ${EXECDIR}${/}cert.pem
+    ${result}=  Fetch From Left  ${file_content}  -----END CERTIFICATE-----
+    ${cert_content}=  Fetch From Right  ${result}  -----BEGIN CERTIFICATE-----
+
+    ${result}=  Fetch From Left  ${file_content}  -----END PRIVATE KEY-----
+    ${private_key_content}=  Fetch From Right  ${result}  -----BEGIN PRIVATE KEY-----
+
+    ${cert_data}=
+    ...  Run Keyword if  '${cert_format}' == 'Valid Certificate Valid Privatekey'
+    ...  OperatingSystem.Get File  ${EXECDIR}${/}cert.pem
+    ...  ELSE IF  '${cert_format}' == 'Empty Certificate Valid Privatekey'
+    ...  Remove String  ${file_content}  ${cert_content}
+    ...  ELSE IF  '${cert_format}' == 'Valid Certificate Empty Privatekey'
+    ...  Remove String  ${file_content}  ${private_key_content}
+    ...  ELSE IF  '${cert_format}' == 'Empty Certificate Empty Privatekey'
+    ...  Remove String  ${file_content}  ${cert_content}  ${private_key_content}
+    ...  ELSE IF  '${cert_format}' == 'Expired Certificate'
+    ...  OperatingSystem.Get File  ${EXECDIR}${/}cert.pem
+
+    ${random_name}=  Generate Random String  8
+    ${cert_name}=  Catenate  SEPARATOR=  ${random_name}  .pem
+    Create File  ${cert_name}  ${cert_data}
+
+    [Return]  ${EXECDIR}${/}${cert_name}
+
+
+Get Certificate Content From File
+    [Documentation]  Get certificate content from certificate file.
+    [Arguments]  ${cert_file_path}
+
+    # Description of argument(s):
+    # cert_file_path  Downloaded certificate file path.
+
+    ${file_content}=  OperatingSystem.Get File  ${cert_file_path}
+    ${result}=  Fetch From Left  ${file_content}  -----END CERTIFICATE-----
+    ${result}=  Fetch From Right  ${result}  -----BEGIN CERTIFICATE-----
+    [Return]  ${result}
+
+
+Check If Openssl Tool Exist
+    [Documentation]  Check if openssl tool installed or not.
+
+    ${rc}  ${output}=  Run And Return RC and Output  which openssl
+    Should Not Be Empty  ${output}  msg=Openssl tool not installed.
+
diff --git a/tests/test_certificate.robot b/tests/test_certificate.robot
new file mode 100755
index 0000000..784b706
--- /dev/null
+++ b/tests/test_certificate.robot
@@ -0,0 +1,205 @@
+*** Settings ***
+
+Documentation  Test certificate in OpenBMC.
+
+Resource       ../lib/rest_client.robot
+Resource       ../lib/resource.txt
+Resource       ../lib/openbmc_ffdc.robot
+Resource       ../lib/certificate_utils.robot
+
+Test Teardown  FFDC On Test Case Fail
+
+
+*** Test Cases ***
+
+Test Server Certificate Install With Valid Certificate And Valid Private Key
+    [Documentation]  Test server certificate install with valid certificate
+    ...  and valid private key.
+    [Tags]  Test_Server_Certificate_Install_With_Valid_Certificate_And_Valid_Private_Key
+    [Template]  Certificate Install Via REST
+    # Certificate type    Certificate file format             Expected Status
+    Server                Valid Certificate Valid Privatekey  ok
+
+
+Test Server Certificate Install With Empty Certificate And Valid Private Key
+    [Documentation]  Test server certificate install with empty certificate
+    ...  and valid private key.
+    [Tags]  Test_Server_Certificate_Install_With_Empty_Certificate_And_Valid_Private_Key
+    [Template]  Certificate Install Via REST
+
+    # Certificate type    Certificate file format             Expected Status
+    Server                Empty Certificate Valid Privatekey  error
+
+
+Test Server Certificate Install With Valid Certificate And Empty Private Key
+    [Documentation]  Test server certificate install with valid certificate
+    ...  and empty private key.
+    [Tags]  Test_Server_Certificate_Install_With_Valid_Certificate_And_Empty_Private_Key
+    [Template]  Certificate Install Via REST
+
+    # Certificate type    Certificate file format             Expected Status
+    Server                Valid Certificate Empty Privatekey  error
+
+
+Test Server Certificate Install With Empty Certificate And Empty Private Key
+    [Documentation]  Test server certificate install with empty certificate
+    ...  and empty private key.
+    [Tags]  Test_Server_Certificate_Install_With_Empty_Certificate_And_Empty_Private_Key
+    [Template]  Certificate Install Via REST
+
+    # Certificate type    Certificate file format             Expected Status
+    Server                Empty Certificate Empty Privatekey  error
+
+
+Test Server Certificate Install With Expired Certificate
+    [Documentation]  Test server certificate install with expired certificate.
+    [Tags]  Test_Server_Certificate_Install_With_Expired_Certificate
+    [Template]  Certificate Install Via REST
+    # Certificate type    Certificate file format             Expected Status
+    Server                Expired Certificate                 error
+
+
+Test Client Certificate Install With Valid Certificate And Valid Private Key
+    [Documentation]  Test client certificate install with valid certificate
+    ...  and valid private key.
+    [Tags]  Test_Client_Certificate_Install_With_Valid_Certificate_And_Valid_Private_Key
+    [Template]  Certificate Install Via REST
+    # Certificate type    Certificate file format             Expected Status
+    Client                Valid Certificate Valid Privatekey  ok
+
+
+Test Client Certificate Install With Empty Certificate And Valid Private Key
+    [Documentation]  Test client certificate install with empty certificate
+    ...  and valid private key.
+    [Tags]  Test_Client_Certificate_Install_With_Empty_Certificate_And_Valid_Private_Key
+    [Template]  Certificate Install Via REST
+
+    # Certificate type    Certificate file format             Expected Status
+    Client                Empty Certificate Valid Privatekey  error
+
+
+Test Client Certificate Install With Valid Certificate And Empty Private Key
+    [Documentation]  Test client certificate install with valid certificate
+    ...  and empty private key.
+    [Tags]  Test_Client_Certificate_Install_With_Valid_Certificate_And_Empty_Private_Key
+    [Template]  Certificate Install Via REST
+
+    # Certificate type    Certificate file format             Expected Status
+    Client                Valid Certificate Empty Privatekey  error
+
+
+Test Client Certificate Install With Empty Certificate And Empty Private Key
+    [Documentation]  Test client certificate install with empty certificate
+    ...  and empty private key.
+    [Tags]  Test_Client_Certificate_Install_With_Empty_Certificate_And_Empty_Private_Key
+    [Template]  Certificate Install Via REST
+
+    # Certificate type    Certificate file format             Expected Status
+    Client                Empty Certificate Empty Privatekey  error
+
+
+Test Client Certificate Install With Expired Certificate
+    [Documentation]  Test client certificate install with expired certificate.
+    [Tags]  Test_Client_Certificate_Install_With_Expired_Certificate
+    [Template]  Certificate Install Via REST
+    # Certificate type    Certificate file format             Expected Status
+    Client                Expired Certificate                 error
+
+
+Test Delete Server Certificate
+    [Documentation]  Delete server certificate and verify.
+    [Tags]  Test_Delete_Server_Certificate
+
+    ${cert_file_path}=  Generate Certificate File Via Openssl
+    ...  Valid Certificate Valid Privatekey
+    ${file_data}=  OperatingSystem.Get Binary File  ${cert_file_path}
+    ${cert_file_content}=  OperatingSystem.Get File  ${cert_file_path}
+
+    Install Certificate File On BMC  ${SERVER_CERTIFICATE_URI}
+    ...  data=${file_data}
+
+    OpenBMC Delete Request  ${SERVER_CERTIFICATE_URI}
+    # Adding delay after certificate deletion
+    Sleep  10s
+
+    ${bmc_cert_content}=  Get Certificate Content From BMC Via Openssl
+    Should Not Contain  ${cert_file_content}  ${bmc_cert_content}
+
+
+Test Delete Client Certificate
+    [Documentation]  Delete client certificate and verify.
+    [Tags]  Test_Delete_Client_Certificate
+
+    ${cert_file_path}=  Generate Certificate File Via Openssl
+    ...  Valid Certificate Valid Privatekey
+    ${file_data}=  OperatingSystem.Get Binary File  ${cert_file_path}
+    ${cert_file_content}=  OperatingSystem.Get File  ${cert_file_path}
+
+    Install Certificate File On BMC  ${CLIENT_CERTIFICATE_URI}
+    ...  data=${file_data}
+
+    OpenBMC Delete Request  ${CLIENT_CERTIFICATE_URI}
+    # Adding delay after certificate deletion
+    Sleep  30s
+
+    ${bmc_cert_content}=  Get Client Certificate File Content From BMC
+
+    Should Not Contain  ${cert_file_content}  ${bmc_cert_content}
+
+
+Test Continuous Server Certificate Install
+    [Documentation]  Stress server certificate installtion.
+    [Tags]  Test_Continuous_Server_Certificate_Install
+
+    Repeat Keyword  50 times  Certificate Install Via REST
+    ...  Server  Valid Certificate Valid Privatekey  ok
+
+
+Test Continuous Client Certificate Install
+    [Documentation]  Stress client certificate installtion.
+    [Tags]  Test_Continuous_Client_Certificate_Install
+
+    Repeat Keyword  50 times  Certificate Install Via REST
+    ...  Client  Valid Certificate Valid Privatekey  ok
+
+
+***Keywords***
+
+Certificate Install Via REST
+    [Documentation]  Test certificate install in the BMC via REST.
+    [Arguments]  ${cert_type}  ${cert_format}  ${expected_status}
+
+    # Description of argument(s):
+    # cert_type           Certificate type (e.g. "Server" or "Client").
+    # cert_format         Certificate file format
+    #                     (e.g. Valid_Certificate_Valid_Privatekey).
+    # expected_status     Expected status of certificate installation REST
+    #                     request(i.e. "ok" or "error").
+
+    ${cert_file_path}=  Run Keyword if  '${cert_format}' == 'Expired Certificate'
+    ...  Generate Certificate File Via Openssl  ${cert_format}  -10
+    ...  ELSE  Generate Certificate File Via Openssl  ${cert_format}
+
+    ${file_data}=  OperatingSystem.Get Binary File  ${cert_file_path}
+
+    Run Keyword If  '${cert_type}' == 'Server'
+    ...    Install Certificate File On BMC  ${SERVER_CERTIFICATE_URI}
+    ...    ${expected_status}  ${1}  data=${file_data}
+    ...  ELSE IF  '${cert_type}' == 'Client'
+    ...    Install Certificate File On BMC  ${CLIENT_CERTIFICATE_URI}
+    ...    ${expected_status}  ${1}  data=${file_data}
+
+    # Adding delay after certificate installation.
+    sleep  10s
+    ${cert_file_content}=  OperatingSystem.Get File  ${cert_file_path}
+    Should Not Be Empty  ${cert_file_content}
+
+    ${bmc_cert_content}=  Run Keyword If  '${cert_type}' == 'Server'
+    ...    Get Certificate Content From BMC Via Openssl
+    ...  ELSE IF  '${cert_type}' == 'Client'
+    ...    Get Client Certificate File Content From BMC
+
+    Run Keyword if  '${expected_status}' == 'ok'
+    ...  Should Contain  ${cert_file_content}  ${bmc_cert_content}
+    ...  ELSE IF  '${expected_status}' == 'error'
+    ...  Should Not Contain  ${cert_file_content}  ${bmc_cert_content}