Skip to content

Commit

Permalink
Allow cosigned to validate Fulcio signatures. (#867)
Browse files Browse the repository at this point in the history
This change makes it so that when `cosigned` is enabled on a namespace, and no public key is provided the webhook will verify things against the Fulcio root.

The basic idea here is that this roughly matches the CLI where omitting the key will verify things against the Fulcio root instead.

Related: #866

Signed-off-by: Matt Moore <mattomata@gmail.com>
  • Loading branch information
mattmoor committed Oct 11, 2021
1 parent b0408bf commit 2ba1605
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 17 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/kind-e2e-cosigned.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,6 @@ jobs:
run: |
ko apply -Bf config/
# Update the cosign verification-key secret with a proper key pair.
cosign generate-key-pair k8s://cosign-system/verification-key
# Wait for the webhook to come up and become Ready
kubectl rollout status --timeout 5m --namespace cosign-system deployments/webhook
Expand Down
29 changes: 21 additions & 8 deletions pkg/cosign/kubernetes/webhook/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,26 @@ import (
)

func valid(ctx context.Context, ref name.Reference, keys []*ecdsa.PublicKey) bool {
if len(keys) == 0 {
// If there are no keys, then verify against the fulcio root.
sps, err := validSignatures(ctx, ref, nil /* verifier */)
if err != nil {
logging.FromContext(ctx).Errorf("error validating signatures: %v", err)
return false
}
if len(sps) > 0 {
return true
}
return false
}
for _, k := range keys {
sps, err := validSignatures(ctx, ref, k)
verifier, err := signature.LoadECDSAVerifier(k, crypto.SHA256)
if err != nil {
logging.FromContext(ctx).Errorf("error creating verifier: %v", err)
return false
}

sps, err := validSignatures(ctx, ref, verifier)
if err != nil {
logging.FromContext(ctx).Errorf("error validating signatures: %v", err)
return false
Expand All @@ -51,15 +69,10 @@ func valid(ctx context.Context, ref name.Reference, keys []*ecdsa.PublicKey) boo
// For testing
var cosignVerifySignatures = cosign.VerifySignatures

func validSignatures(ctx context.Context, ref name.Reference, key *ecdsa.PublicKey) ([]oci.Signature, error) {
ecdsaVerifier, err := signature.LoadECDSAVerifier(key, crypto.SHA256)
if err != nil {
return nil, err
}

func validSignatures(ctx context.Context, ref name.Reference, verifier signature.Verifier) ([]oci.Signature, error) {
sigs, _, err := cosignVerifySignatures(ctx, ref, &cosign.CheckOpts{
RootCerts: fulcioroots.Get(),
SigVerifier: ecdsaVerifier,
SigVerifier: verifier,
ClaimVerifier: cosign.SimpleClaimVerifier,
})
return sigs, err
Expand Down
7 changes: 1 addition & 6 deletions pkg/cosign/kubernetes/webhook/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,7 @@ func TestValidateCronJob(t *testing.T) {
Name: secretName,
},
Data: map[string][]byte{
// Random public key (cosign generate-key-pair) 2021-09-25
"cosign.pub": []byte(`-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEapTW568kniCbL0OXBFIhuhOboeox
UoJou2P8sbDxpLiE/v3yLw1/jyOrCPWYHWFXnyyeGlkgSVefG54tNoK7Uw==
-----END PUBLIC KEY-----
`),
// No data should make us verify against Fulcio.
},
})

Expand Down
38 changes: 38 additions & 0 deletions test/e2e_test_cosigned.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ spec:
- name: sample
image: $KO_DOCKER_REPO/sample
EOF
cat > distroless-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
generateName: pod-test-
spec:
restartPolicy: Never
containers:
- name: sample
image: gcr.io/distroless/base:debug
command: [/busybox/sh, -c]
args:
- |
echo Testing Fulcio verification
EOF
cat > job.yaml <<EOF
apiVersion: batch/v1
kind: Job
Expand Down Expand Up @@ -62,6 +77,29 @@ EOF
echo '::endgroup::'


echo '::group:: enable verification'
kubectl label namespace default --overwrite cosigned.sigstore.dev/include=true
echo '::endgroup::'


echo '::group:: test pod success (Fulcio root)'
# This time it should succeed!
if ! kubectl create -f distroless-pod.yaml ; then
echo Failed to create Pod signed by Fulcio!
exit 1
else
echo Successfully created Pod signed by Fulcio.
fi
echo '::endgroup::'


echo '::group:: setup verification-key'
# Update the cosign verification-key secret with a proper key pair.
cosign generate-key-pair k8s://cosign-system/verification-key
echo '::endgroup::'



echo '::group:: disable verification'
kubectl label namespace default --overwrite cosigned.sigstore.dev/include=false
echo '::endgroup::'
Expand Down

0 comments on commit 2ba1605

Please sign in to comment.