mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Fix PEM delimiter parse (#4331)
* update log levels Signed-off-by: Jim Bugwadia <jim@nirmata.com> * do not generate policy reports for blocked images Signed-off-by: Jim Bugwadia <jim@nirmata.com> * fix PEM delimiter parsing and add test case Signed-off-by: Jim Bugwadia <jim@nirmata.com> Signed-off-by: Jim Bugwadia <jim@nirmata.com>
This commit is contained in:
parent
b02da637b2
commit
22eb79a7f0
2 changed files with 81 additions and 7 deletions
|
@ -142,7 +142,7 @@ func buildCosignOptions(opts Options) (*cosign.CheckOpts, error) {
|
|||
}
|
||||
|
||||
if opts.Key != "" {
|
||||
if strings.HasPrefix(opts.Key, "-----BEGIN PUBLIC KEY-----") {
|
||||
if strings.HasPrefix(strings.TrimSpace(opts.Key), "-----BEGIN PUBLIC KEY-----") {
|
||||
cosignOpts.SigVerifier, err = decodePEM([]byte(opts.Key))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load public key from PEM")
|
||||
|
@ -426,14 +426,17 @@ func extractDigest(imgRef string, payload []payload.SimpleContainerImage) (strin
|
|||
if digest := p.Critical.Image.DockerManifestDigest; digest != "" {
|
||||
return digest, nil
|
||||
} else {
|
||||
logger.Info("failed to extract image digest from verification response", "image", imgRef, "payload", p)
|
||||
return "", fmt.Errorf("unknown image response for " + imgRef)
|
||||
return "", fmt.Errorf("failed to extract image digest from signature payload for " + imgRef)
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("digest not found for " + imgRef)
|
||||
}
|
||||
|
||||
func matchCertificate(signatures []oci.Signature, subject, issuer string, extensions map[string]string) error {
|
||||
if subject == "" && issuer == "" && len(extensions) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, sig := range signatures {
|
||||
cert, err := sig.Cert()
|
||||
if err != nil {
|
||||
|
|
|
@ -132,15 +132,19 @@ var testResource = `{
|
|||
}
|
||||
}`
|
||||
|
||||
var payloads = [][]byte{
|
||||
var attestationPayloads = [][]byte{
|
||||
[]byte(`{"payloadType":"https://example.com/CodeReview/v1","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2V4YW1wbGUuY29tL0NvZGVSZXZpZXcvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2hjci5pby9qaW1idWd3YWRpYS9wYXVzZTIiLCJkaWdlc3QiOnsic2hhMjU2IjoiYjMxYmZiNGQwMjEzZjI1NGQzNjFlMDA3OWRlYWFlYmVmYTRmODJiYTdhYTc2ZWY4MmU5MGI0OTM1YWQ1YjEwNSJ9fV0sInByZWRpY2F0ZSI6eyJhdXRob3IiOiJtYWlsdG86YWxpY2VAZXhhbXBsZS5jb20iLCJyZXBvIjp7ImJyYW5jaCI6Im1haW4iLCJ0eXBlIjoiZ2l0IiwidXJpIjoiaHR0cHM6Ly9naXRodWIuY29tL2V4YW1wbGUvbXktcHJvamVjdCJ9LCJyZXZpZXdlcnMiOlsibWFpbHRvOmJvYkBleGFtcGxlLmNvbSJdfX0=","signatures":[{"keyid":"","sig":"MEYCIQCrEr+vgPDmNCrqGDE/4z9iMLmCXMXcDlGKtSoiuMTSFgIhAN2riBaGk4accWzVl7ypi1XTRxyrPYHst8DesugPXgOf"}]}`),
|
||||
[]byte(`{"payloadType":"cosign.sigstore.dev/attestation/v1","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJjb3NpZ24uc2lnc3RvcmUuZGV2L2F0dGVzdGF0aW9uL3YxIiwic3ViamVjdCI6W3sibmFtZSI6ImdoY3IuaW8vamltYnVnd2FkaWEvcGF1c2UyIiwiZGlnZXN0Ijp7InNoYTI1NiI6ImIzMWJmYjRkMDIxM2YyNTRkMzYxZTAwNzlkZWFhZWJlZmE0ZjgyYmE3YWE3NmVmODJlOTBiNDkzNWFkNWIxMDUifX1dLCJwcmVkaWNhdGUiOnsiRGF0YSI6ImhlbGxvIVxuIiwiVGltZXN0YW1wIjoiMjAyMS0xMC0wNVQwNToxODoxMVoifX0=","signatures":[{"keyid":"","sig":"MEQCIF5r9lf55rnYNPByZ9v6bortww694UEPvmyBIelIDYbIAiBNTGX4V64Oj6jZVRpkJQRxdzKUPYqC5GZTb4oS6eQ6aQ=="}]}`),
|
||||
[]byte(`{"payloadType":"https://example.com/CodeReview/v1","payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL2V4YW1wbGUuY29tL0NvZGVSZXZpZXcvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoiZ2hjci5pby9qaW1idWd3YWRpYS9wYXVzZTIiLCJkaWdlc3QiOnsic2hhMjU2IjoiYjMxYmZiNGQwMjEzZjI1NGQzNjFlMDA3OWRlYWFlYmVmYTRmODJiYTdhYTc2ZWY4MmU5MGI0OTM1YWQ1YjEwNSJ9fV0sInByZWRpY2F0ZSI6eyJhdXRob3IiOiJtYWlsdG86YWxpY2VAZXhhbXBsZS5jb20iLCJyZXBvIjp7ImJyYW5jaCI6Im1haW4iLCJ0eXBlIjoiZ2l0IiwidXJpIjoiaHR0cHM6Ly9naXRodWIuY29tL2V4YW1wbGUvbXktcHJvamVjdCJ9LCJyZXZpZXdlcnMiOlsibWFpbHRvOmJvYkBleGFtcGxlLmNvbSJdfX0=","signatures":[{"keyid":"","sig":"MEUCIEeZbdBEFQzWqiMhB+SJgM6yFppUuQSKrpOIX1mxLDmRAiEA8pXqFq0GVc9LKhPzrnJRZhSruDNiKbiLHG5x7ETFyY8="}]}`),
|
||||
}
|
||||
|
||||
var signaturePayloads = [][]byte{
|
||||
[]byte(`{"critical":{"identity":{"docker-reference":"ghcr.io/kyverno/test-verify-image"},"image":{"docker-manifest-digest":"sha256:b31bfb4d0213f254d361e0079deaaebefa4f82ba7aa76ef82e90b4935ad5b105"},"type":"cosign container image signature"},"optional":null}`),
|
||||
}
|
||||
|
||||
func Test_CosignMockAttest(t *testing.T) {
|
||||
policyContext := buildContext(t, testPolicyGood, testResource, "")
|
||||
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", payloads)
|
||||
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", attestationPayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er, ivm := VerifyAndPatchImages(policyContext)
|
||||
|
@ -152,7 +156,7 @@ func Test_CosignMockAttest(t *testing.T) {
|
|||
|
||||
func Test_CosignMockAttest_fail(t *testing.T) {
|
||||
policyContext := buildContext(t, testPolicyBad, testResource, "")
|
||||
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", payloads)
|
||||
err := cosign.SetMock("ghcr.io/jimbugwadia/pause2:latest", attestationPayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
er, _ := VerifyAndPatchImages(policyContext)
|
||||
|
@ -579,7 +583,7 @@ func Test_MarkImageVerified(t *testing.T) {
|
|||
image := "ghcr.io/jimbugwadia/pause2:latest"
|
||||
cosign.ClearMock()
|
||||
policyContext := buildContext(t, testPolicyGood, testResource, "")
|
||||
err := cosign.SetMock(image, payloads)
|
||||
err := cosign.SetMock(image, attestationPayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
engineResponse, verifiedImages := VerifyAndPatchImages(policyContext)
|
||||
|
@ -618,3 +622,70 @@ func applyPatches(t *testing.T, patches [][]byte) unstructured.Unstructured {
|
|||
assert.NilError(t, err)
|
||||
return u
|
||||
}
|
||||
|
||||
func Test_ParsePEMDelimited(t *testing.T) {
|
||||
testPEMPolicy := `{
|
||||
"apiVersion": "kyverno.io/v1",
|
||||
"kind": "Policy",
|
||||
"metadata": {
|
||||
"name": "check-image"
|
||||
},
|
||||
"spec": {
|
||||
"validationFailureAction": "enforce",
|
||||
"background": false,
|
||||
"webhookTimeoutSeconds": 30,
|
||||
"failurePolicy": "Fail",
|
||||
"rules": [
|
||||
{
|
||||
"name": "check-image",
|
||||
"match": {
|
||||
"any": [
|
||||
{
|
||||
"resources": {
|
||||
"kinds": [
|
||||
"Pod"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"verifyImages": [
|
||||
{
|
||||
"imageReferences": [
|
||||
"*"
|
||||
],
|
||||
"attestors": [
|
||||
{
|
||||
"count": 1,
|
||||
"entries": [
|
||||
{
|
||||
"keys": {
|
||||
"publicKeys": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfVMHGmFK4OgVqhy36KZ7a3r4R4/o\nCwaCVvXZV4ZULFbkFZ0IodGqKqcVmgycnoj7d8TpKpAUVNF8kKh90ewH3A==\n-----END PUBLIC KEY-----\n-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0f1W0XigyPFbX8Xq3QmkbL9gDFTf\nRfc8jF7UadBcwKxiyvPSOKZn+igQfXzpNjrwPSZ58JGvF4Fs8BB3fSRP2g==\n-----END PUBLIC KEY-----"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
image := "ghcr.io/jimbugwadia/pause2:latest"
|
||||
cosign.ClearMock()
|
||||
policyContext := buildContext(t, testPEMPolicy, testResource, "")
|
||||
err := cosign.SetMock(image, signaturePayloads)
|
||||
assert.NilError(t, err)
|
||||
|
||||
engineResponse, verifiedImages := VerifyAndPatchImages(policyContext)
|
||||
assert.Assert(t, engineResponse != nil)
|
||||
assert.Equal(t, len(engineResponse.PolicyResponse.Rules), 1)
|
||||
assert.Equal(t, engineResponse.PolicyResponse.Rules[0].Status, response.RuleStatusPass)
|
||||
|
||||
assert.Assert(t, verifiedImages != nil)
|
||||
assert.Assert(t, verifiedImages.Data != nil)
|
||||
assert.Equal(t, len(verifiedImages.Data), 1)
|
||||
assert.Equal(t, verifiedImages.isVerified(image), true)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue