Change AAF Certservice CSITs to send requests via HTTPS 19/104519/7
authorAleksandra Maciaga <aleksandra.maciaga@nokia.com>
Thu, 26 Mar 2020 16:28:47 +0000 (17:28 +0100)
committerMichal Banka <michal.banka@nokia.com>
Fri, 3 Apr 2020 13:16:10 +0000 (15:16 +0200)
Signed-off-by: Aleksandra Maciaga <aleksandra.maciaga@nokia.com>
Signed-off-by: Michal Banka <michal.banka@nokia.com>
Change-Id: Ia7b5d8d548f4ae3727302772fc56e6b0142b0da0
Issue-ID: AAF-1084

plans/aaf/certservice/certs/Makefile [new file with mode: 0644]
plans/aaf/certservice/docker-compose.yml
plans/aaf/certservice/setup.sh
plans/aaf/certservice/teardown.sh
tests/aaf/certservice/assets/invalid_client_docker.env
tests/aaf/certservice/assets/valid_client_docker.env
tests/aaf/certservice/libraries/CertClientManager.py
tests/aaf/certservice/resources/cert-service-keywords.robot
tests/aaf/certservice/resources/cert-service-properties.robot

diff --git a/plans/aaf/certservice/certs/Makefile b/plans/aaf/certservice/certs/Makefile
new file mode 100644 (file)
index 0000000..126e053
--- /dev/null
@@ -0,0 +1,110 @@
+all: step_1 step_2 step_3 step_4 step_5 step_6 step_7 step_8 step_9 step_10 step_11 step_12 step_13 step_14 step_15
+.PHONY: all
+#Clear certificates
+clear:
+       @echo "Clear certificates"
+       rm -f certServiceClient-keystore.jks certServiceServer-keystore.jks root.crt truststore.jks certServiceServer-keystore.p12
+       @echo "#####done#####"
+
+#Generate root private and public keys
+step_1:
+       @echo "Generate root private and public keys"
+       keytool -genkeypair -v -alias root -keyalg RSA -keysize 4096 -validity 3650 -keystore root-keystore.jks \
+    -dname "CN=root.com, OU=Root Org, O=Root Company, L=Wroclaw, ST=Dolny Slask, C=PL" -keypass secret \
+    -storepass secret -ext BasicConstraints:critical="ca:true"
+       @echo "#####done#####"
+
+#Export public key as certificate
+step_2:
+       @echo "(Export public key as certificate)"
+       keytool -exportcert -alias root -keystore root-keystore.jks -storepass secret -file root.crt -rfc
+       @echo "#####done#####"
+
+#Self-signed root (import root certificate into truststore)
+step_3:
+       @echo "(Self-signed root (import root certificate into truststore))"
+       keytool -importcert -alias root -keystore truststore.jks -file root.crt -storepass secret -noprompt
+       @echo "#####done#####"
+
+#Generate certService's client private and public keys
+step_4:
+       @echo "Generate certService's client private and public keys"
+       keytool -genkeypair -v -alias certServiceClient -keyalg RSA -keysize 2048 -validity 730 \
+    -keystore certServiceClient-keystore.jks -storetype JKS \
+    -dname "CN=certServiceClient.com,OU=certServiceClient company,O=certServiceClient org,L=Wroclaw,ST=Dolny Slask,C=PL" \
+    -keypass secret -storepass secret
+       @echo "####done####"
+
+#Generate certificate signing request for certService's client
+step_5:
+       @echo "Generate certificate signing request for certService's client"
+       keytool -certreq -keystore certServiceClient-keystore.jks -alias certServiceClient -storepass secret -file certServiceClient.csr
+       @echo "####done####"
+
+#Sign certService's client certificate by root CA
+step_6:
+       @echo "Sign certService's client certificate by root CA"
+       keytool -gencert -v -keystore root-keystore.jks -storepass secret -alias root -infile certServiceClient.csr \
+    -outfile certServiceClientByRoot.crt -rfc -ext bc=0  -ext ExtendedkeyUsage="serverAuth,clientAuth"
+       @echo "####done####"
+
+#Import root certificate into client
+step_7:
+       @echo "Import root certificate into intermediate"
+       cat root.crt >> certServiceClientByRoot.crt
+       @echo "####done####"
+
+#Import signed certificate into certService's client
+step_8:
+       @echo "Import signed certificate into certService's client"
+       keytool -importcert -file certServiceClientByRoot.crt -destkeystore certServiceClient-keystore.jks -alias certServiceClient -storepass secret -noprompt
+       @echo "####done####"
+
+#Generate certService private and public keys
+step_9:
+       @echo "Generate certService private and public keys"
+       keytool -genkeypair -v -alias aaf-cert-service -keyalg RSA -keysize 2048 -validity 730 \
+    -keystore certServiceServer-keystore.jks -storetype JKS \
+    -dname "CN=aaf-cert-service,OU=certServiceServer company,O=certServiceServer org,L=Wroclaw,ST=Dolny Slask,C=PL" \
+    -keypass secret -storepass secret -ext BasicConstraints:critical="ca:false"
+       @echo "####done####"
+
+#Generate certificate signing request for certService
+step_10:
+       @echo "Generate certificate signing request for certService"
+       keytool -certreq -keystore certServiceServer-keystore.jks -alias aaf-cert-service -storepass secret -file certServiceServer.csr
+       @echo "####done####"
+
+#Sign certService certificate by root CA
+step_11:
+       @echo "Sign certService certificate by root CA"
+       keytool -gencert -v -keystore root-keystore.jks -storepass secret -alias root -infile certServiceServer.csr \
+    -outfile certServiceServerByRoot.crt -rfc -ext bc=0  -ext ExtendedkeyUsage="serverAuth,clientAuth" \
+    -ext SubjectAlternativeName:="DNS:aaf-cert-service,DNS:localhost"
+       @echo "####done####"
+
+#Import root certificate into server
+step_12:
+       @echo "Import root certificate into intermediate(server)"
+       cat root.crt >> certServiceServerByRoot.crt
+       @echo "####done####"
+
+#Import signed certificate into certService
+step_13:
+       @echo "Import signed certificate into certService"
+       keytool -importcert -file certServiceServerByRoot.crt -destkeystore certServiceServer-keystore.jks -alias aaf-cert-service \
+    -storepass secret -noprompt
+       @echo "####done####"
+
+#Convert certServiceServer-keystore(.jks) to PCKS12 format(.p12)
+step_14:
+       @echo "Convert certServiceServer-keystore(.jks) to PCKS12 format(.p12)"
+       keytool -importkeystore -srckeystore certServiceServer-keystore.jks -srcstorepass secret \
+        -destkeystore certServiceServer-keystore.p12 -deststoretype PKCS12 -deststorepass secret
+       @echo "#####done#####"
+
+#Clear unused certificates
+step_15:
+       @echo "Clear unused certificates"
+       rm -f certServiceClientByRoot.crt certServiceClient.csr root-keystore.jks certServiceServerByRoot.crt  certServiceServer.csr
+       @echo "#####done#####"
index ae7ee87..dcac7df 100644 (file)
@@ -10,9 +10,6 @@ services:
       - "443:8443"
     volumes:
       - $SCRIPTS_PATH:/opt/primekey/scripts
-    command: bash -c "
-      /opt/primekey/bin/start.sh
-      "
     healthcheck:
       test: ["CMD-SHELL", "curl -kI https://localhost:8443/ejbca/publicweb/healthcheck/ejbcahealth"]
       interval: 20s
@@ -21,16 +18,25 @@ services:
     networks:
       - certservice
 
-  certservice:
+  aaf-cert-service:
     image: nexus3.onap.org:10001/onap/org.onap.aaf.certservice.aaf-certservice-api:latest
     volumes:
       - $CONFIGURATION_PATH:/etc/onap/aaf/certservice/cmpServers.json
-    container_name: aafcert
+      - ./certs/truststore.jks:/etc/onap/aaf/certservice/certs/truststore.jks
+      - ./certs/root.crt:/etc/onap/aaf/certservice/certs/root.crt
+      - ./certs/certServiceServer-keystore.jks:/etc/onap/aaf/certservice/certs/certServiceServer-keystore.jks
+      - ./certs/certServiceServer-keystore.p12:/etc/onap/aaf/certservice/certs/certServiceServer-keystore.p12
+    container_name: aafcert-service
     ports:
-      - "8080:8080"
+      - "8443:8443"
     depends_on:
       ejbca:
         condition: service_healthy
+    healthcheck:
+      test: ["CMD-SHELL", "curl https://localhost:8443/actuator/health --cacert /etc/onap/aaf/certservice/certs/root.crt --cert-type p12 --cert /etc/onap/aaf/certservice/certs/certServiceServer-keystore.p12 --pass secret"]
+      interval: 10s
+      timeout: 3s
+      retries: 15
     networks:
       - certservice
 
index 93d65f7..b23b719 100644 (file)
@@ -71,15 +71,26 @@ echo "Use configuration from: $CONFIGURATION_PATH"
 export CONFIGURATION_PATH=${CONFIGURATION_PATH}
 export SCRIPTS_PATH=${SCRIPTS_PATH}
 
+#Generate keystores, truststores, certificates and keys
+mkdir -p ${WORKSPACE}/tests/aaf/certservice/assets/certs/
+make all -C ./certs/
+cp ${WORKSPACE}/plans/aaf/certservice/certs/root.crt ${WORKSPACE}/tests/aaf/certservice/assets/certs/root.crt
+echo "Generated keystores"
+openssl pkcs12 -in ${WORKSPACE}/plans/aaf/certservice/certs/certServiceServer-keystore.p12 -clcerts -nokeys -password pass:secret | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ${WORKSPACE}/tests/aaf/certservice/assets/certs/certServiceServer.crt
+echo "Generated server certificate"
+openssl pkcs12 -in ${WORKSPACE}/plans/aaf/certservice/certs/certServiceServer-keystore.p12 -nocerts -nodes -password pass:secret| sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' > ${WORKSPACE}/tests/aaf/certservice/assets/certs/certServiceServer.key
+echo "Generated server key"
+
 docker-compose up -d
 
 AAFCERT_IP='none'
 # Wait container ready
 for i in {1..9}
 do
-   AAFCERT_IP=`get-instance-ip.sh aafcert`
-   RESP_CODE=$(curl -I -s -o /dev/null -w "%{http_code}"  http://${AAFCERT_IP}:8080/actuator/health)
-   if [[ "$RESP_CODE" == '200' ]]; then
+   AAFCERT_IP=`get-instance-ip.sh aafcert-service`
+   RESP_CODE=$(curl -s https://localhost:8443/actuator/health --cacert ./certs/root.crt --cert-type p12 --cert ./certs/certServiceServer-keystore.p12 --pass secret | \
+   python2 -c 'import json,sys;obj=json.load(sys.stdin);print obj["status"]')
+   if [[ "$RESP_CODE" == "UP" ]]; then
        echo 'AAF Cert Service is ready'
        export AAFCERT_IP=${AAFCERT_IP}
        docker exec aafcert-ejbca /opt/primekey/scripts/ejbca-configuration.sh
index 83737f0..71e20b7 100644 (file)
@@ -17,4 +17,9 @@
 
 docker-compose down
 
+make clear -C ./certs/
+echo "Removed old keystores"
+rm -rf ${WORKSPACE}/tests/aaf/certservice/assets/certs
+echo "Removed old certificates"
+
 kill-instance.sh ${ClientContainerName}
\ No newline at end of file
index 3e7d879..e96237c 100644 (file)
@@ -2,6 +2,10 @@
 REQUEST_TIMEOUT=5000
 OUTPUT_PATH=/var/certs
 CA_NAME=Invalid
+KEYSTORE_PATH=/etc/onap/aaf/certservice/certs/certServiceClient-keystore.jks
+KEYSTORE_PASSWORD=secret
+TRUSTSTORE_PATH=/etc/onap/aaf/certservice/certs/truststore.jks
+TRUSTSTORE_PASSWORD=secret
 #Csr config envs
 COMMON_NAME=onap.org
 ORGANIZATION=Linux-Foundation
index 0181896..55fefa3 100644 (file)
@@ -2,6 +2,10 @@
 REQUEST_TIMEOUT=30000
 OUTPUT_PATH=/var/certs
 CA_NAME=RA
+KEYSTORE_PATH=/etc/onap/aaf/certservice/certs/certServiceClient-keystore.jks
+KEYSTORE_PASSWORD=secret
+TRUSTSTORE_PATH=/etc/onap/aaf/certservice/certs/truststore.jks
+TRUSTSTORE_PASSWORD=secret
 #Csr config envs
 COMMON_NAME=onap.org
 ORGANIZATION=Linux-Foundation
index a959c9e..a4a0df2 100644 (file)
@@ -10,10 +10,12 @@ ARCHIVES_PATH = os.getenv("WORKSPACE") + "/archives/"
 ERROR_API_REGEX = 'Error on API response.*[0-9]{3}'
 RESPONSE_CODE_REGEX = '[0-9]{3}'
 
+
 class CertClientManager:
 
-    def __init__(self, mount_path):
+    def __init__(self, mount_path, truststore_path):
         self.mount_path = mount_path
+        self.truststore_path = truststore_path
 
     def run_client_container(self, client_image, container_name, path_to_env, request_url, network):
         self.create_mount_dir()
@@ -25,8 +27,9 @@ class CertClientManager:
             name=container_name,
             environment=environment,
             network=network,
-            user='root', #Run container as root to avoid permission issues with volume mount access
-            mounts=[Mount(target='/var/certs', source=self.mount_path, type='bind')],
+            user='root',  # Run container as root to avoid permission issues with volume mount access
+            mounts=[Mount(target='/var/certs', source=self.mount_path, type='bind'),
+                    Mount(target='/etc/onap/aaf/certservice/certs/', source=self.truststore_path, type='bind')],
             detach=True
         )
         exitcode = container.wait()
index a128178..d4d4fd9 100644 (file)
@@ -5,19 +5,20 @@ Resource          ./cert-service-properties.robot
 Library              RequestsLibrary
 Library           HttpLibrary.HTTP
 Library           Collections
-Library           ../libraries/CertClientManager.py  ${MOUNT_PATH}
+Library           ../libraries/CertClientManager.py  ${MOUNT_PATH}  ${TRUSTSTORE_PATH}
 Library           ../libraries/JksFilesValidator.py  ${MOUNT_PATH}
 
 *** Keywords ***
 
 Create sessions
     [Documentation]  Create all required sessions
-    Create Session    aaf_cert_service_url    ${AAFCERT_URL}
-    Set Suite Variable    ${http_session}    aaf_cert_service_url
+    ${certs}=  Create List  ${CERTSERVICE_SERVER_CRT}  ${CERTSERVICE_SERVER_KEY}
+    Create Client Cert Session  alias  ${AAFCERT_URL}  client_certs=${certs}  verify=${ROOTCA}
+    Set Suite Variable  ${https_valid_cert_session}  alias
 
 Run Healthcheck
     [Documentation]  Run Healthcheck
-    ${resp}=   Get Request     ${http_session}         /actuator/health
+    ${resp}=  Get Request      ${https_valid_cert_session}     /actuator/health
     Should Be Equal As Strings         ${resp.status_code}     200
     Validate Recieved Response  ${resp}  status  UP
 
@@ -31,7 +32,7 @@ Validate Recieved Response
 Send Get Request And Validate Response
     [Documentation]   Send request to passed url and validate received response
     [Arguments]   ${path}  ${resp_code}
-    ${resp}=   Get Request     ${http_session}  ${path}
+    ${resp}=   Get Request     ${https_valid_cert_session}  ${path}
     Should Be Equal As Strings         ${resp.status_code}     ${resp_code}
 
 Send Get Request with Header
@@ -39,7 +40,7 @@ Send Get Request with Header
     [Arguments]  ${path}  ${csr_file}  ${pk_file}
     [Return]  ${resp}
     ${headers}=  Create Header with CSR and PK  ${csr_file}  ${pk_file}
-    ${resp}=   Get Request     ${http_session}  ${path}  headers=${headers}
+    ${resp}=   Get Request     ${https_valid_cert_session}  ${path}  headers=${headers}
 
 Send Get Request with Header And Expect Success
     [Documentation]   Send request to passed url and validate received response
@@ -81,7 +82,7 @@ Create Header with CSR and PK
 Send Post Request And Validate Response
     [Documentation]   Send request to passed url and validate received response
     [Arguments]   ${path}  ${resp_code}
-    ${resp}=   Post Request    ${http_session}  ${path}
+    ${resp}=   Post Request    ${https_valid_cert_session}  ${path}
     Should Be Equal As Strings         ${resp.status_code}     ${resp_code}
 
 Run Cert Service Client And Validate JKS File Creation And Client Exit Code
index 0dd8b06..53d6b24 100644 (file)
@@ -1,10 +1,14 @@
 *** Variables ***
 
-${CERT_SERVICE_PORT}                     8080
-${AAFCERT_URL}                           http://localhost:${cert_service_port}
+${CERT_SERVICE_CONTAINER_NAME}           aaf-cert-service
+${CERT_SERVICE_PORT}                     8443
+${AAFCERT_URL}                           https://localhost:${cert_service_port}
 ${CLIENT_CA_NAME}                        Client
 ${RA_CA_NAME}                            RA
 ${CERT_SERVICE_ENDPOINT}                 /v1/certificate/
+${ROOTCA}                                %{WORKSPACE}/tests/aaf/certservice/assets/certs/root.crt
+${CERTSERVICE_SERVER_CRT}                %{WORKSPACE}/tests/aaf/certservice/assets/certs/certServiceServer.crt
+${CERTSERVICE_SERVER_KEY}                %{WORKSPACE}/tests/aaf/certservice/assets/certs/certServiceServer.key
 ${VALID_CLIENT_CSR_FILE}                 %{WORKSPACE}/tests/aaf/certservice/assets/valid_client.csr
 ${VALID_CLIENT_PK_FILE}                  %{WORKSPACE}/tests/aaf/certservice/assets/valid_client.pk
 ${VALID_RA_CSR_FILE}                     %{WORKSPACE}/tests/aaf/certservice/assets/valid_ra.csr
@@ -13,10 +17,11 @@ ${INVALID_CSR_FILE}                      %{WORKSPACE}/tests/aaf/certservice/asse
 ${INVALID_PK_FILE}                       %{WORKSPACE}/tests/aaf/certservice/assets/invalid.key
 
 
-${CERT_SERVICE_ADDRESS}                  http://%{AAFCERT_IP}:${cert_service_port}
+${CERT_SERVICE_ADDRESS}                  https://${CERT_SERVICE_CONTAINER_NAME}:${CERT_SERVICE_PORT}
 ${VALID_ENV_FILE}                        %{WORKSPACE}/tests/aaf/certservice/assets/valid_client_docker.env
 ${INVALID_ENV_FILE}                      %{WORKSPACE}/tests/aaf/certservice/assets/invalid_client_docker.env
 ${DOCKER_CLIENT_IMAGE}                   nexus3.onap.org:10001/onap/org.onap.aaf.certservice.aaf-certservice-client:latest
 ${CLIENT_CONTAINER_NAME}                 %{ClientContainerName}
 ${CERT_SERVICE_NETWORK}                  certservice_certservice
 ${MOUNT_PATH}                            %{WORKSPACE}/tests/aaf/certservice/tmp
+${TRUSTSTORE_PATH}                       %{WORKSPACE}/plans/aaf/certservice/certs