mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
handle Cosign payload variations
Signed-off-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
parent
4835157cc4
commit
f35bbe77b7
2 changed files with 95 additions and 13 deletions
|
@ -6,12 +6,13 @@ import (
|
|||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/in-toto/in-toto-golang/in_toto"
|
||||
"github.com/kyverno/kyverno/pkg/engine/common"
|
||||
"github.com/sigstore/cosign/cmd/cosign/cli/fulcio"
|
||||
"github.com/sigstore/cosign/pkg/cosign/attestation"
|
||||
"github.com/sigstore/sigstore/pkg/signature/dsse"
|
||||
"strings"
|
||||
|
||||
"github.com/gardener/controller-manager-library/pkg/logger"
|
||||
"github.com/go-logr/logr"
|
||||
|
@ -259,9 +260,9 @@ func extractDigest(imgRef string, verified []cosign.SignedPayload, log logr.Logg
|
|||
return "", err
|
||||
}
|
||||
|
||||
log.V(4).Info("image verification response", "image", imgRef, "payload", jsonMap)
|
||||
log.V(3).Info("image verification response", "image", imgRef, "payload", jsonMap)
|
||||
|
||||
// The cosign response is in the JSON format:
|
||||
// The expected payload is in one of these JSON formats:
|
||||
// {
|
||||
// "critical": {
|
||||
// "identity": {
|
||||
|
@ -274,20 +275,52 @@ func extractDigest(imgRef string, verified []cosign.SignedPayload, log logr.Logg
|
|||
// },
|
||||
// "optional": null
|
||||
// }
|
||||
critical := jsonMap["critical"].(map[string]interface{})
|
||||
//
|
||||
// {
|
||||
// "Critical": {
|
||||
// "Identity": {
|
||||
// "docker-reference": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop"
|
||||
// },
|
||||
// "Image": {
|
||||
// "Docker-manifest-digest": "sha256:6a037d5ba27d9c6be32a9038bfe676fb67d2e4145b4f53e9c61fb3e69f06e816"
|
||||
// },
|
||||
// "Type": "Tekton container signature"
|
||||
// },
|
||||
// "Optional": {}
|
||||
// }
|
||||
//
|
||||
critical := getMapValue(jsonMap, "critical", "Critical")
|
||||
if critical != nil {
|
||||
typeStr := critical["type"].(string)
|
||||
if typeStr == "cosign container image signature" {
|
||||
identity := critical["identity"].(map[string]interface{})
|
||||
if identity != nil {
|
||||
image := critical["image"].(map[string]interface{})
|
||||
if image != nil {
|
||||
return image["docker-manifest-digest"].(string), nil
|
||||
}
|
||||
}
|
||||
image := getMapValue(critical, "image", "Image")
|
||||
if image != nil {
|
||||
digest := getStringValue(image, "docker-manifest-digest", "Docker-manifest-digest")
|
||||
return digest, nil
|
||||
}
|
||||
} else {
|
||||
log.Info("failed to extract image digest from verification response", "image", imgRef, "payload", jsonMap)
|
||||
return "", fmt.Errorf("unknown image response for " + imgRef)
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("digest not found for " + imgRef)
|
||||
}
|
||||
|
||||
func getMapValue(m map[string]interface{}, keys ...string) map[string]interface{} {
|
||||
for _, k := range keys {
|
||||
if m[k] != nil {
|
||||
return m[k].(map[string]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getStringValue(m map[string]interface{}, keys ...string) string {
|
||||
for _, k := range keys {
|
||||
if m[k] != nil {
|
||||
return m[k].(string)
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
|
49
pkg/cosign/cosign_test.go
Normal file
49
pkg/cosign/cosign_test.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
package cosign
|
||||
|
||||
import (
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/sigstore/cosign/pkg/cosign"
|
||||
"gotest.tools/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const cosignPayload = `{
|
||||
"critical": {
|
||||
"identity": {
|
||||
"docker-reference": "registry-v2.nirmata.io/pause"
|
||||
},
|
||||
"image": {
|
||||
"docker-manifest-digest": "sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108"
|
||||
},
|
||||
"type": "cosign container image signature"
|
||||
},
|
||||
"optional": null
|
||||
}`
|
||||
|
||||
const tektonPayload = `{
|
||||
"Critical": {
|
||||
"Identity": {
|
||||
"docker-reference": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop"
|
||||
},
|
||||
"Image": {
|
||||
"Docker-manifest-digest": "sha256:6a037d5ba27d9c6be32a9038bfe676fb67d2e4145b4f53e9c61fb3e69f06e816"
|
||||
},
|
||||
"Type": "Tekton container signature"
|
||||
},
|
||||
"Optional": {}
|
||||
}`
|
||||
|
||||
func TestCosignPayload(t *testing.T) {
|
||||
var log logr.Logger = logr.DiscardLogger{}
|
||||
image := "registry-v2.nirmata.io/pause"
|
||||
signedPayloads := []cosign.SignedPayload{{Payload: []byte(cosignPayload)}}
|
||||
d, err := extractDigest(image, signedPayloads, log)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, d, "sha256:4a1c4b21597c1b4415bdbecb28a3296c6b5e23ca4f9feeb599860a1dac6a0108")
|
||||
|
||||
image2 := "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop"
|
||||
signedPayloads2 := []cosign.SignedPayload{{Payload: []byte(tektonPayload)}}
|
||||
d2, err := extractDigest(image2, signedPayloads2, log)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, d2, "sha256:6a037d5ba27d9c6be32a9038bfe676fb67d2e4145b4f53e9c61fb3e69f06e816")
|
||||
}
|
Loading…
Add table
Reference in a new issue