From 7cc7829cc01cbe05af4419bae91e75b5b24a9089 Mon Sep 17 00:00:00 2001 From: Alex Carter Date: Mon, 23 Jan 2023 18:36:18 +0000 Subject: [PATCH] CC: Add image signature tests for SEV Inserts resource information to kbs for signing adds example cosign and policy files to be used along with signing tests Adds tests for: signed image with no required measurement signed image with no required measurement, but wrong key signed image with required measurement signed image with invalid measurement Fixes: #5412 --- .../confidential/fixtures/cosign.pub | 4 + .../confidential/fixtures/cosignWrong.pub | 4 + .../confidential/fixtures/policy.json | 30 ++++ integration/kubernetes/confidential/sev.bats | 136 +++++++++++++++++- versions.yaml | 2 +- 5 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 integration/kubernetes/confidential/fixtures/cosign.pub create mode 100644 integration/kubernetes/confidential/fixtures/cosignWrong.pub create mode 100644 integration/kubernetes/confidential/fixtures/policy.json diff --git a/integration/kubernetes/confidential/fixtures/cosign.pub b/integration/kubernetes/confidential/fixtures/cosign.pub new file mode 100644 index 000000000..9920c37c0 --- /dev/null +++ b/integration/kubernetes/confidential/fixtures/cosign.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1gHGbfk1AqOweLEM8HfT0bmfQE3b +9fcp/LU75FMfxVZXmNVtUprsHM1thuuiBKOofv8KV7TrFl4p8NJCiXUkhA== +-----END PUBLIC KEY----- diff --git a/integration/kubernetes/confidential/fixtures/cosignWrong.pub b/integration/kubernetes/confidential/fixtures/cosignWrong.pub new file mode 100644 index 000000000..cc8da380f --- /dev/null +++ b/integration/kubernetes/confidential/fixtures/cosignWrong.pub @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwkHKoZIzj0CAQYIKoZIzj0DAkcDQgAE1gHGbfk1AqOweoEM8HfT0bmf2E3b +9fcp/LU75FMfxVZXmNVtUprsHM1thuuiBKOofv8KV7TrFl4p8NJCiXUkhA== +-----END PUBLIC KEY----- diff --git a/integration/kubernetes/confidential/fixtures/policy.json b/integration/kubernetes/confidential/fixtures/policy.json new file mode 100644 index 000000000..c2bc471cd --- /dev/null +++ b/integration/kubernetes/confidential/fixtures/policy.json @@ -0,0 +1,30 @@ +{ + "default": [ + { + "type": "insecureAcceptAnything" + } + ], + "transports": { + "docker": { + "quay.io/kata-containers/confidential-containers": [ + { + "type": "signedBy", + "keyType": "GPGKeys", + "keyPath": "/run/image-security/simple_signing/pubkey.gpg" + } + ], + "quay.io/kata-containers/confidential-containers:cosign-signed": [ + { + "type": "sigstoreSigned", + "keyPath": "/run/image-security/cosign/cosign.pub" + } + ], + "quay.io/kata-containers/confidential-containers:cosign-signed-key2": [ + { + "type": "sigstoreSigned", + "keyPath": "/run/image-security/cosign/cosign.pub" + } + ] + } + } +} \ No newline at end of file diff --git a/integration/kubernetes/confidential/sev.bats b/integration/kubernetes/confidential/sev.bats index 2c63bfa39..048141e30 100644 --- a/integration/kubernetes/confidential/sev.bats +++ b/integration/kubernetes/confidential/sev.bats @@ -150,18 +150,26 @@ delete_pods() { local encrypted_pod_name=$(esudo kubectl get pod -o wide | grep encrypted-image-tests | awk '{print $1;}' || true) local unencrypted_pod_name=$(esudo kubectl get pod -o wide | grep unencrypted-image-tests | awk '{print $1;}' || true) local encrypted_pod_name_es=$(esudo kubectl get pod -o wide | grep encrypted-image-tests-es | awk '{print $1;}' || true) + local signed_pod_name=$(esudo kubectl get pod -o wide | grep signed-image-tests | awk '{print $1;}' || true) + local signed_pod_wrong_name=$(esudo kubectl get pod -o wide | grep signed-image-tests | awk '{print $1;}' || true) - # Delete both encrypted and unencrypted pods + # Delete encrypted, unencrypted, and signed pods esudo kubectl delete -f \ "${TEST_DIR}/unencrypted-image-tests.yaml" 2>/dev/null || true esudo kubectl delete -f \ "${TEST_DIR}/encrypted-image-tests.yaml" 2>/dev/null || true esudo kubectl delete -f \ "${TEST_DIR}/encrypted-image-tests-es.yaml" 2>/dev/null || true - + esudo kubectl delete -f \ + "${TEST_DIR}/signed-image-tests.yaml" 2>/dev/null || true + esudo kubectl delete -f \ + "${TEST_DIR}/signed-image-wrong.yaml" 2>/dev/null || true + [ -z "${encrypted_pod_name}" ] || (kubernetes_wait_for_pod_delete_state "${encrypted_pod_name}" || true) [ -z "${unencrypted_pod_name}" ] || (kubernetes_wait_for_pod_delete_state "${unencrypted_pod_name}" || true) [ -z "${encrypted_pod_name_es}" ] || (kubernetes_wait_for_pod_delete_state "${encrypted_pod_name_es}" || true) + [ -z "${signed_pod_name}" ] || (kubernetes_wait_for_pod_delete_state "${signed_pod_name}" || true) + [ -z "${signed_pod_wrong_name}" ] || (kubernetes_wait_for_pod_delete_state "${signed_pod_wrong_name}" || true) } run_kbs() { @@ -177,6 +185,12 @@ run_kbs() { pushd simple-kbs git checkout -b "branch_${simple_kbs_tag}" "${simple_kbs_tag}" + + #copy resources + cp ${TESTS_REPO_DIR}/integration/kubernetes/confidential/fixtures/policy.json resources/ + cp ${TESTS_REPO_DIR}/integration/kubernetes/confidential/fixtures/cosign.pub resources/ + #cp ${TESTS_REPO_DIR}/integration/kubernetes/confidential/fixtures/cosignWrong.pub resources/ + esudo docker-compose build esudo docker-compose up -d @@ -315,6 +329,8 @@ setup_file() { generate_service_yaml "unencrypted-image-tests" "${IMAGE_REPO}:unencrypted" generate_service_yaml "encrypted-image-tests" "${IMAGE_REPO}:encrypted" + generate_service_yaml "signed-image-tests" "quay.io/kata-containers/confidential-containers:cosign-signed" + generate_service_yaml "signed-image-wrong" "quay.io/kata-containers/confidential-containers:cosign-signed-key2" # SEV-ES policy is 7: # - NODBG (1): Debugging of the guest is disallowed when set @@ -336,13 +352,35 @@ setup() { DELETE FROM secrets WHERE id = 10; DELETE FROM keysets WHERE id = 10; DELETE FROM policy WHERE id = 10; + DELETE FROM resources WHERE id = 10; EOF } +setup_cosign_signatures_files() { + measurement=${1} + + if [ -n "${measurement}" ]; then + mysql -u${KBS_DB_USER} -p${KBS_DB_PW} -h ${KBS_DB_HOST} -D ${KBS_DB} < "${TEST_DIR}/guest-kernel-append" + echo "Kernel Append Retrieved from QEMU Process: ${kernel_append}" +} + +@test "$test_tag Test signed image with no required measurement, but wrong key (failure)" { + # Add resource files to + setup_cosign_signatures_files #"cosignWrong.pub" + + #change kernel command line for signature validation + esudo sed -i 's/agent.enable_signature_verification=false/agent.enable_signature_verification=true/g' ${SEV_CONFIG} + + # Start the service/deployment/pod + esudo kubectl apply -f "${TEST_DIR}/signed-image-wrong.yaml" + + # Retrieve pod name, wait for it to come up, retrieve pod ip + pod_name=$(esudo kubectl get pod -o wide | grep signed-image-wrong | awk '{print $1;}') + kubernetes_wait_for_pod_ready_state "$pod_name" 30 || true + + print_service_info + + # Get pod info + pod_info=$(esudo kubectl describe pod ${pod_name}) + # Check failure condition + if [[ ! ${pod_info} =~ "Validate image failed" ]]; then + >&2 echo -e "${RED}TEST - FAIL${NC}" + return 1 + else + echo "Pod message contains: Validate image failed" + echo -e "${GREEN}TEST - PASS${NC}" + fi +} + +@test "$test_tag Test signed image with required measurement" { + #change kernel command line for signature validation + esudo sed -i 's/agent.enable_signature_verification=false/agent.enable_signature_verification=true/g' ${SEV_CONFIG} + + # Generate firmware measurement + local append=$(cat ${TEST_DIR}/guest-kernel-append) + echo "Kernel Append: ${append}" + measurement=$(generate_firmware_measurement_with_append "${append}") + echo "Firmware Measurement: ${measurement}" + + # Add resource files to + setup_cosign_signatures_files ${measurement} + + # Start the service/deployment/pod + esudo kubectl apply -f "${TEST_DIR}/signed-image-tests.yaml" + + # Retrieve pod name, wait for it to come up, retrieve pod ip + pod_name=$(esudo kubectl get pod -o wide | grep signed-image-tests | awk '{print $1;}') + kubernetes_wait_for_pod_ready_state "$pod_name" 50 + + print_service_info +} + +@test "$test_tag Test signed image with INVALID measurement" { + #change kernel command line for signature validation + esudo sed -i 's/agent.enable_signature_verification=false/agent.enable_signature_verification=true/g' ${SEV_CONFIG} + + # Generate firmware measurement + local append="INVALID-INPUT" + measurement=$(generate_firmware_measurement_with_append ${append}) + echo "Firmware Measurement: ${measurement}" + + # Add resource files to + setup_cosign_signatures_files ${measurement} + + # Start the service/deployment/pod + esudo kubectl apply -f "${TEST_DIR}/signed-image-tests.yaml" + + # Retrieve pod name, wait for it to come up, retrieve pod ip + pod_name=$(esudo kubectl get pod -o wide | grep signed-image-tests | awk '{print $1;}') + kubernetes_wait_for_pod_ready_state "$pod_name" 20 || true + + print_service_info +} teardown_file() { echo "###############################################################################" diff --git a/versions.yaml b/versions.yaml index 120a0e40c..21a18a56c 100644 --- a/versions.yaml +++ b/versions.yaml @@ -72,7 +72,7 @@ externals: simple-kbs: description: "Simple KBS that hosts key storage with release policies" url: "https://github.com/confidential-containers/simple-kbs.git" - tag: "0.1.1" + tag: "v0.1.2" sonobuoy: description: "Tool to run kubernetes e2e conformance tests"