Skip to content

Commit

Permalink
fix merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
priyawadhwa committed Jun 26, 2023
2 parents 3026bcf + 4ef480e commit 5c719a6
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 263 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:

- uses: sigstore/cosign-installer@dd6b2e2b610a11fd73dd187a43d57cc1394e35f9

- uses: anchore/sbom-action/download-syft@4d571ad1038a9cc29d676154ef265ab8f9027042 # v0.14.2
- uses: anchore/sbom-action/download-syft@78fc58e266e87a38d4194b2137a3d4e9bcaf7ca1 # v0.14.3

- uses: ko-build/setup-ko@ace48d793556083a76f1e3e6068850c1f4a369aa # v0.6

Expand Down
6 changes: 3 additions & 3 deletions pkg/policy/verifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const (
// It is verifiable with goodPolicy.
staticDigest = "sha256:39ae0654d64cb72003216f6148e581e6d7cf239ac32325867af46666e31739d2"

// This is the digest of ghcr.io/distroless/static as of 2023/01/03.
// This is the digest of cgr.dev/chainguard/static as of 2023/01/03.
// It is not verifiable with goodPolicy.
ancientDigest = "sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b"
)
Expand Down Expand Up @@ -68,7 +68,7 @@ func TestVerifierDeny(t *testing.T) {
}},
},
d: name.MustParseReference("cgr.dev/chainguard/static@" + ancientDigest).(name.Digest),
wantErr: errors.New("signature keyless validation failed for authority authority-0 for cgr.dev/chainguard/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b: no matching signatures:\nnone of the expected identities matched what was in the certificate, got subjects [https://github.com/distroless/static/.github/workflows/release.yaml@refs/heads/main] with issuer https://token.actions.githubusercontent.com: "),
wantErr: errors.New("signature keyless validation failed for authority authority-0 for cgr.dev/chainguard/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b: no matching signatures: none of the expected identities matched what was in the certificate, got subjects [https://github.com/distroless/static/.github/workflows/release.yaml@refs/heads/main] with issuer https://token.actions.githubusercontent.com: "),
}}

for _, test := range tests {
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestVerifierWarn(t *testing.T) {
}},
},
d: name.MustParseReference("cgr.dev/chainguard/static@" + ancientDigest).(name.Digest),
wantErr: errors.New("signature keyless validation failed for authority authority-0 for cgr.dev/chainguard/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b: no matching signatures:\nnone of the expected identities matched what was in the certificate, got subjects [https://github.com/distroless/static/.github/workflows/release.yaml@refs/heads/main] with issuer https://token.actions.githubusercontent.com: "),
wantErr: errors.New("signature keyless validation failed for authority authority-0 for cgr.dev/chainguard/static@sha256:a9650a15060275287ebf4530b34020b8d998bd2de9aea00d113c332d8c41eb0b: no matching signatures: none of the expected identities matched what was in the certificate, got subjects [https://github.com/distroless/static/.github/workflows/release.yaml@refs/heads/main] with issuer https://token.actions.githubusercontent.com: "),
}, {
name: "duplicate policies",
v: Verification{
Expand Down
8 changes: 8 additions & 0 deletions pkg/webhook/testdata/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-----BEGIN CERTIFICATE-----
MIHwMIGXoAMCAQICAQEwCgYIKoZIzj0EAwIwADAiGA8wMDAxMDEwMTAwMDAwMFoY
DzAwMDEwMTAxMDAwMDAwWjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMP4j
1NMREAE3IpA1ihHN1xZFThO4oFdeRWbVTIUDhgOcCDVh5K/pmquzDE3uqG1D9TmZ
wC5pPyURDgJ9dzTvjDAKBggqhkjOPQQDAgNIADBFAiEAtCfQlhemMkHHz+Brj9ls
f1iHbBF+q2r9Ijud52yFeYoCIESU129jdhqmhm1yWb0bI95dCTEaiKLZaQ8mK+OV
1yr2
-----END CERTIFICATE-----
46 changes: 38 additions & 8 deletions pkg/webhook/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -642,9 +644,9 @@ func ociSignatureToPolicySignature(ctx context.Context, sigs []oci.Signature) []
for _, ociSig := range sigs {
logging.FromContext(ctx).Debugf("Converting signature %+v", ociSig)

id, err := ociSig.Digest()
sigID, err := signatureID(ociSig)
if err != nil {
logging.FromContext(ctx).Debugf("Error fetching signature digest %+v", err)
logging.FromContext(ctx).Debugf("Error fetching signature %+v", err)
continue
}

Expand All @@ -653,7 +655,7 @@ func ociSignatureToPolicySignature(ctx context.Context, sigs []oci.Signature) []
Cert: cert,
}
ret = append(ret, PolicySignature{
ID: id.Hex,
ID: sigID,
Subject: csigs.CertSubject(cert),
Issuer: ce.GetIssuer(),
GithubExtensions: GithubExtensions{
Expand All @@ -666,14 +668,42 @@ func ociSignatureToPolicySignature(ctx context.Context, sigs []oci.Signature) []
})
} else {
ret = append(ret, PolicySignature{
ID: id.Hex,
ID: sigID,
// TODO(mattmoor): Is there anything we should encode for key-based?
})
}
}
return ret
}

// signatureID creates a unique hash for the Signature, using both the signature itself + the cert.
func signatureID(sig oci.Signature) (string, error) {
h := sha256.New()
s, err := sig.Signature()
if err != nil {
return "", err
}
if _, err := h.Write(s); err != nil {
return "", err
}

cert, err := sig.Cert()
if err != nil {
return "", err
}
if cert != nil {
c, err := cryptoutils.MarshalCertificateToPEM(cert)
if err != nil {
return "", err
}
if _, err := h.Write(c); err != nil {
return "", err
}
}

return hex.EncodeToString(h.Sum(nil)), nil
}

// attestation is used to accumulate the signature along with extracted and
// validated metadata during validation to construct a list of
// PolicyAttestations upon completion without needing to refetch any of the
Expand All @@ -690,9 +720,9 @@ func attestationToPolicyAttestations(ctx context.Context, atts []attestation) []
for _, att := range atts {
logging.FromContext(ctx).Debugf("Converting attestation %+v", att)

id, err := att.Digest()
sigID, err := signatureID(att.Signature)
if err != nil {
logging.FromContext(ctx).Debugf("Error fetching attestation digest %+v", err)
logging.FromContext(ctx).Debugf("Error fetching attestation signature %+v", err)
continue
}

Expand All @@ -702,7 +732,7 @@ func attestationToPolicyAttestations(ctx context.Context, atts []attestation) []
}
ret = append(ret, PolicyAttestation{
PolicySignature: PolicySignature{
ID: id.Hex,
ID: sigID,
Subject: csigs.CertSubject(cert),
Issuer: ce.GetIssuer(),
GithubExtensions: GithubExtensions{
Expand All @@ -719,7 +749,7 @@ func attestationToPolicyAttestations(ctx context.Context, atts []attestation) []
} else {
ret = append(ret, PolicyAttestation{
PolicySignature: PolicySignature{
ID: id.Hex,
ID: sigID,
// TODO(mattmoor): Is there anything we should encode for key-based?
},
PredicateType: att.PredicateType,
Expand Down
59 changes: 55 additions & 4 deletions pkg/webhook/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"os"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -1764,7 +1764,7 @@ func TestValidatePolicy(t *testing.T) {
Attestations: map[string][]PolicyAttestation{
"test-att": {{
PolicySignature: PolicySignature{
ID: "01bd6aec99ad7c5d045d9aab649fd95b7af2b3b23887d34d7fce8b2e3c38ca0e",
ID: "00016978d0723c9bc73c599d296ab4052a392e37746509c1f5038494ca4bf34a",
Subject: "https://github.com/distroless/static/.github/workflows/release.yaml@refs/heads/main",
Issuer: "https://token.actions.githubusercontent.com",
GithubExtensions: GithubExtensions{
Expand Down Expand Up @@ -1817,8 +1817,8 @@ func TestValidatePolicy(t *testing.T) {
}
got, gotErrs := ValidatePolicy(testContext, system.Namespace(), digest, test.policy, kc)
validateErrors(t, test.wantErrs, gotErrs)
if !reflect.DeepEqual(test.want, got) {
t.Errorf("unexpected PolicyResult, want: %+v got: %+v", test.want, got)
if diff := cmp.Diff(test.want, got); diff != "" {
t.Errorf("unexpected PolicyResult, %s", diff)
}
})
}
Expand Down Expand Up @@ -3271,3 +3271,54 @@ func TestCheckOptsFromAuthority(t *testing.T) {
})
}
}

func TestSignatureID(t *testing.T) {
cert := mustRead(t, "testdata/cert.pem")
for _, tc := range []struct {
name string
sig oci.Signature
want string
}{
{
name: "no cert",
sig: newStaticSig(t, []byte("foo"), nil),
want: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
},
{
name: "with cert",
sig: newStaticSig(t, []byte("foo"), cert),
want: "0b413181a61e85e0426d9f49ccd58d2205314297ee0c3bb515ad9d0f89480995",
},
} {
got, err := signatureID(tc.sig)
if err != nil {
t.Fatal(err)
}
if tc.want != got {
t.Errorf("want %s, got %s", tc.want, got)
}
}
}

func mustRead(t *testing.T, path string) []byte {
t.Helper()
b, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
return b
}

func newStaticSig(t *testing.T, payload []byte, cert []byte) oci.Signature {
t.Helper()

var opts []static.Option
if cert != nil {
opts = append(opts, static.WithCertChain(cert, nil))
}
out, err := static.NewSignature(payload, "", opts...)
if err != nil {
t.Fatal(err)
}
return out
}
2 changes: 1 addition & 1 deletion test/e2e_test_cluster_image_policy_no_tuf.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ echo '::endgroup::'
# This image has not been signed with our key
# so should fail
echo '::group:: test job rejection'
expected_error='no signatures found for image'
expected_error='no matching signatures'
assert_error ${expected_error}
echo '::endgroup::'

Expand Down
2 changes: 1 addition & 1 deletion test/e2e_test_cluster_image_policy_with_attestations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ echo '::endgroup::'

# This image has not been signed at all, so should get auto-reject
echo '::group:: test job rejection'
expected_error='no signatures found for image'
expected_error='no matching signatures'
assert_error ${expected_error}
echo '::endgroup::'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ echo '::endgroup::'

# This image has not been signed at all, so should get auto-reject
echo '::group:: test job rejection'
expected_error='no signatures found for image'
expected_error='no matching signatures'
assert_error ${expected_error}
echo '::endgroup::'

Expand Down
2 changes: 1 addition & 1 deletion test/e2e_test_cluster_image_policy_with_source.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ sleep 5
echo '::endgroup::'

echo '::group:: test job rejection using an OCI source to a wrong repository without signatures'
expected_error='no signatures found for image'
expected_error='no matching signatures'
assert_error ${expected_error}
echo '::endgroup::'

Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 5c719a6

Please sign in to comment.