Skip to content

Commit

Permalink
Test authority key integration
Browse files Browse the repository at this point in the history
Signed-off-by: Denny Hoang <dhoang@vmware.com>
  • Loading branch information
DennyHoang committed Mar 21, 2022
1 parent d6f266a commit 1aa88d1
Showing 1 changed file with 89 additions and 14 deletions.
103 changes: 89 additions & 14 deletions pkg/cosign/kubernetes/webhook/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
package webhook

import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/x509"
"errors"
"testing"
"time"
Expand Down Expand Up @@ -52,6 +56,21 @@ func TestValidatePodSpec(t *testing.T) {

secretName := "blah"

var authorityKeyCosignPub *ecdsa.PublicKey
// Random public key (cosign generate-key-pair) 2022-03-18
authorityKeyCosignPubString := `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENAyijLvRu5QpCPp2uOj8C79ZW1VJ
SID/4H61ZiRzN4nqONzp+ZF22qQTk3MFO3D0/ZKmWHAosIf2pf2GHH7myA==
-----END PUBLIC KEY-----`

pems := parsePems([]byte(authorityKeyCosignPubString))
if len(pems) > 0 {
key, _ := x509.ParsePKIXPublicKey(pems[0].Bytes)
authorityKeyCosignPub = key.(*ecdsa.PublicKey)
} else {
t.Errorf("Error parsing authority key from string")
}

si.Informer().GetIndexer().Add(&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: system.Namespace(),
Expand Down Expand Up @@ -93,11 +112,27 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
return nil, false, errors.New("bad signature")
}

// Let's say it is verified if it is the expected Public Key
authorityPublicKeyCVS := func(ctx context.Context, signedImgRef name.Reference, co *cosign.CheckOpts) (checkedSignatures []oci.Signature, bundleVerified bool, err error) {
actualPublicKey, _ := co.SigVerifier.PublicKey()
actualECDSAPubkey := actualPublicKey.(*ecdsa.PublicKey)
actualKeyData := elliptic.Marshal(actualECDSAPubkey, actualECDSAPubkey.X, actualECDSAPubkey.Y)

expectedKeyData := elliptic.Marshal(authorityKeyCosignPub, authorityKeyCosignPub.X, authorityKeyCosignPub.Y)

if bytes.Equal(actualKeyData, expectedKeyData) {
return pass(ctx, signedImgRef, co)
}

return fail(ctx, signedImgRef, co)
}

tests := []struct {
name string
ps *corev1.PodSpec
want *apis.FieldError
cvs func(context.Context, name.Reference, *cosign.CheckOpts) ([]oci.Signature, bool, error)
name string
ps *corev1.PodSpec
want *apis.FieldError
cvs func(context.Context, name.Reference, *cosign.CheckOpts) ([]oci.Signature, bool, error)
customContext context.Context
}{{
name: "simple, no error",
ps: &corev1.PodSpec{
Expand Down Expand Up @@ -151,14 +186,52 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
Details: digest.String(),
},
cvs: fail,
}, {
name: "simple, no error, authority key",
ps: &corev1.PodSpec{
InitContainers: []corev1.Container{{
Name: "setup-stuff",
Image: digest.String(),
}},
Containers: []corev1.Container{{
Name: "user-container",
Image: digest.String(),
}},
},
customContext: config.ToContext(context.Background(),
&config.Config{
ImagePolicyConfig: &config.ImagePolicyConfig{
Policies: map[string]v1alpha1.ClusterImagePolicySpec{
"cluster-image-policy": {
Images: []v1alpha1.ImagePattern{{
Regex: ".*",
}},
Authorities: []v1alpha1.Authority{
{
Key: &v1alpha1.KeyRef{
Data: authorityKeyCosignPubString,
},
},
},
},
},
},
},
),
cvs: authorityPublicKeyCVS,
}}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cosignVerifySignatures = test.cvs
testContext := context.Background()

if test.customContext != nil {
testContext = test.customContext
}

// Check the core mechanics
got := v.validatePodSpec(context.Background(), test.ps, k8schain.Options{})
got := v.validatePodSpec(testContext, test.ps, k8schain.Options{})
if (got != nil) != (test.want != nil) {
t.Errorf("validatePodSpec() = %v, wanted %v", got, test.want)
} else if got != nil && got.Error() != test.want.Error() {
Expand All @@ -169,7 +242,7 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
pod := &duckv1.Pod{
Spec: *test.ps,
}
got = v.ValidatePod(context.Background(), pod)
got = v.ValidatePod(testContext, pod)
want := test.want.ViaField("spec")
if (got != nil) != (want != nil) {
t.Errorf("ValidatePod() = %v, wanted %v", got, want)
Expand All @@ -178,7 +251,7 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
}
// Check that we don't block things being deleted.
pod.DeletionTimestamp = &metav1.Time{Time: time.Now()}
if got := v.ValidatePod(context.Background(), pod); got != nil {
if got := v.ValidatePod(testContext, pod); got != nil {
t.Errorf("ValidatePod() = %v, wanted nil", got)
}

Expand All @@ -190,7 +263,7 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
},
},
}
got = v.ValidatePodSpecable(context.Background(), withPod)
got = v.ValidatePodSpecable(testContext, withPod)
want = test.want.ViaField("spec.template.spec")
if (got != nil) != (want != nil) {
t.Errorf("ValidatePodSpecable() = %v, wanted %v", got, want)
Expand All @@ -199,7 +272,7 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
}
// Check that we don't block things being deleted.
withPod.DeletionTimestamp = &metav1.Time{Time: time.Now()}
if got := v.ValidatePodSpecable(context.Background(), withPod); got != nil {
if got := v.ValidatePodSpecable(testContext, withPod); got != nil {
t.Errorf("ValidatePodSpecable() = %v, wanted nil", got)
}
})
Expand Down Expand Up @@ -870,8 +943,11 @@ UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==

func TestGetAuthorityKeys(t *testing.T) {
refName := name.MustParseReference("gcr.io/distroless/static:nonroot")

validPublicKey := "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEapTW568kniCbL0OXBFIhuhOboeox\nUoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==\n-----END PUBLIC KEY-----"
// Random public key (cosign generate-key-pair) 2021-09-25
validPublicKey := `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEapTW568kniCbL0OXBFIhuhOboeox
UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
-----END PUBLIC KEY-----`

validKeyData := v1alpha1.Authority{
Key: &v1alpha1.KeyRef{
Expand Down Expand Up @@ -925,9 +1001,8 @@ func TestGetAuthorityKeys(t *testing.T) {
},
wantKeyLength: 1,
},
// TODO: Test against authority[].key.kms and authority[].key.secretRef
// TODO: Test against authority[].keyless
// TODO: Test with multiple imagePatterns
// TODO(dennyhoang): Test against authority[].keyless
// TODO(dennyhoang): Test with more imagePatterns
}

for _, test := range tests {
Expand Down

0 comments on commit 1aa88d1

Please sign in to comment.