feat: add support for oci1.1 cosign signatures(using referrers) (#1963)

- Cosign supports 2 types of signature formats:

	1. Using tag -> each new signature of the same manifest is
	added as a new layer of the signature manifest having that
	specific tag("{alghoritm}-{digest_of_signed_manifest}.sig")

	2. Using referrers -> each new signature of the same manifest is
	added as a new manifest

- For adding these cosign signature to metadb, we reserved index 0 of the
list of cosign signatures for tag-based signatures. When a new tag-based
signature is added for the same manifest, the element on first position
in its list of cosign signatures(in metadb) will be updated/overwritten.
When a new cosign signature(using referrers) will be added for the same
manifest this new signature will be appended to the list of cosign
signatures.

Signed-off-by: Andreea-Lupu <andreealupu1470@yahoo.com>
This commit is contained in:
Andreea Lupu
2023-11-07 00:09:39 +02:00
committed by GitHub
parent 6a66a9b9b4
commit d5065513f5
21 changed files with 511 additions and 85 deletions
+75 -1
View File
@@ -115,7 +115,7 @@ function teardown_file() {
[ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].Licenses') = '"GPLv2"' ]
}
@test "sign/verify with cosign" {
@test "sign/verify with cosign (only tag-based signatures)" {
run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:8080/v2/_zot/ext/search
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
@@ -133,6 +133,80 @@ function teardown_file() {
[[ "$sigName" == *"${digest}"* ]]
}
@test "sign/verify with cosign (only referrers)" {
run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:8080/v2/_zot/ext/search
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
local digest=$(echo "${lines[-1]}" | jq -r '.data.ImageList.Results[0].Manifests[0].Digest')
export COSIGN_OCI_EXPERIMENTAL=1
export COSIGN_EXPERIMENTAL=1
run cosign initialize
[ "$status" -eq 0 ]
run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-experimental"
[ "$status" -eq 0 ]
run cosign sign --registry-referrers-mode=oci-1-1 --key ${BATS_FILE_TMPDIR}/cosign-sign-test-experimental.key localhost:8080/annotations:latest --yes
[ "$status" -eq 0 ]
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-experimental.pub localhost:8080/annotations:latest
[ "$status" -eq 0 ]
local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
[[ "$sigName" == *"${digest}"* ]]
unset COSIGN_OCI_EXPERIMENTAL
unset COSIGN_EXPERIMENTAL
}
@test "sign/verify with cosign (tag and referrers)" {
run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:8080/v2/_zot/ext/search
[ "$status" -eq 0 ]
[ $(echo "${lines[-1]}" | jq '.data.ImageList.Results[0].RepoName') = '"annotations"' ]
local digest=$(echo "${lines[-1]}" | jq -r '.data.ImageList.Results[0].Manifests[0].Digest')
export COSIGN_OCI_EXPERIMENTAL=1
export COSIGN_EXPERIMENTAL=1
run cosign initialize
[ "$status" -eq 0 ]
run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-tag-1"
[ "$status" -eq 0 ]
run cosign sign --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-1.key localhost:8080/annotations:latest --yes
[ "$status" -eq 0 ]
run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-1"
[ "$status" -eq 0 ]
run cosign sign --registry-referrers-mode=oci-1-1 --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-1.key localhost:8080/annotations:latest --yes
[ "$status" -eq 0 ]
run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-tag-2"
[ "$status" -eq 0 ]
run cosign sign --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-2.key localhost:8080/annotations:latest --yes
[ "$status" -eq 0 ]
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-1.pub localhost:8080/annotations:latest
[ "$status" -eq 0 ]
local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
[[ "$sigName" == *"${digest}"* ]]
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-tag-2.pub localhost:8080/annotations:latest
[ "$status" -eq 0 ]
local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
[[ "$sigName" == *"${digest}"* ]]
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-1.pub localhost:8080/annotations:latest
[ "$status" -eq 0 ]
local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
[[ "$sigName" == *"${digest}"* ]]
run cosign generate-key-pair --output-key-prefix "${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-2"
[ "$status" -eq 0 ]
run cosign sign --registry-referrers-mode=oci-1-1 --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-2.key localhost:8080/annotations:latest --yes
[ "$status" -eq 0 ]
run cosign verify --key ${BATS_FILE_TMPDIR}/cosign-sign-test-referrers-2.pub localhost:8080/annotations:latest
[ "$status" -eq 0 ]
local sigName=$(echo "${lines[-1]}" | jq '.[].critical.image."docker-manifest-digest"')
[[ "$sigName" == *"${digest}"* ]]
unset COSIGN_OCI_EXPERIMENTAL
unset COSIGN_EXPERIMENTAL
}
@test "sign/verify with notation" {
run curl -X POST -H "Content-Type: application/json" --data '{ "query": "{ ImageList(repo: \"annotations\") { Results { RepoName Tag Manifests {Digest ConfigDigest Size Layers { Size Digest }} Vendor Licenses }}}"}' http://localhost:8080/v2/_zot/ext/search
[ "$status" -eq 0 ]