1
0
mirror of https://github.com/containers/image.git synced 2025-04-18 19:44:05 +03:00
image/signature/policy_eval_sigstore_test.go
Miloslav Trmač 8dabf442db Remove obsolete build tag syntax
per (go fix ./...).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2025-03-12 20:20:16 +01:00

1058 lines
42 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build !containers_image_fulcio_stub
// Policy evaluation for prCosignSigned.
package signature
import (
"context"
"encoding/base64"
"os"
"testing"
"github.com/containers/image/v5/internal/signature"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPRSigstoreSignedFulcioPrepareTrustRoot(t *testing.T) {
const testCAPath = "fixtures/fulcio_v1.crt.pem"
testCAData, err := os.ReadFile(testCAPath)
require.NoError(t, err)
const testOIDCIssuer = "https://example.com"
testSubjectEmail := "test@example.com"
// Success
for _, c := range [][]PRSigstoreSignedFulcioOption{
{
PRSigstoreSignedFulcioWithCAPath(testCAPath),
PRSigstoreSignedFulcioWithOIDCIssuer(testOIDCIssuer),
PRSigstoreSignedFulcioWithSubjectEmail(testSubjectEmail),
},
{
PRSigstoreSignedFulcioWithCAData(testCAData),
PRSigstoreSignedFulcioWithOIDCIssuer(testOIDCIssuer),
PRSigstoreSignedFulcioWithSubjectEmail(testSubjectEmail),
},
} {
f, err := newPRSigstoreSignedFulcio(c...)
require.NoError(t, err)
res, err := f.prepareTrustRoot()
require.NoError(t, err)
assert.NotNil(t, res.caCertificates) // Doing a better test seems hard; we would need to compare .Subjects with a DER encoding.
assert.Equal(t, testOIDCIssuer, res.oidcIssuer)
assert.Equal(t, testSubjectEmail, res.subjectEmail)
}
// Failure
for _, f := range []prSigstoreSignedFulcio{ // Use a prSigstoreSignedFulcio because these configurations should be rejected by NewPRSigstoreSignedFulcio.
{ // Neither CAPath nor CAData specified
OIDCIssuer: testOIDCIssuer,
SubjectEmail: testSubjectEmail,
},
{ // Both CAPath and CAData specified
CAPath: testCAPath,
CAData: testCAData,
OIDCIssuer: testOIDCIssuer,
SubjectEmail: testSubjectEmail,
},
{ // Invalid CAPath
CAPath: "fixtures/image.signature",
OIDCIssuer: testOIDCIssuer,
SubjectEmail: testSubjectEmail,
},
{ // Unusable CAPath
CAPath: "fixtures/this/does/not/exist",
OIDCIssuer: testOIDCIssuer,
SubjectEmail: testSubjectEmail,
},
{ // Invalid CAData
CAData: []byte("invalid"),
OIDCIssuer: testOIDCIssuer,
SubjectEmail: testSubjectEmail,
},
{ // Missing OIDCIssuer
CAPath: testCAPath,
SubjectEmail: testSubjectEmail,
},
{ // Missing SubjectEmail
CAPath: testCAPath,
OIDCIssuer: testOIDCIssuer,
},
} {
_, err := f.prepareTrustRoot()
assert.Error(t, err)
}
}
func TestPRSigstoreSignedPKIPrepareTrustRoot(t *testing.T) {
const testCARootsPath = "fixtures/pki_root_crts.pem"
const testCAIntermediatesPath = "fixtures/pki_intermediate_crts.pem"
testCARootsData, err := os.ReadFile(testCARootsPath)
require.NoError(t, err)
testCAIntermediatesData, err := os.ReadFile(testCAIntermediatesPath)
require.NoError(t, err)
testSubjectEmail := "test@example.com"
testSubjectHostname := "myhost.example.com"
// Success
for _, c := range []struct {
option []PRSigstoreSignedPKIOption
intermediates bool
subjectEmail string
subjectHostname string
}{
{
option: []PRSigstoreSignedPKIOption{
PRSigstoreSignedPKIWithCARootsPath(testCARootsPath),
PRSigstoreSignedPKIWithSubjectEmail(testSubjectEmail),
PRSigstoreSignedPKIWithSubjectHostname(testSubjectHostname),
},
subjectEmail: testSubjectEmail,
subjectHostname: testSubjectHostname,
},
{
option: []PRSigstoreSignedPKIOption{
PRSigstoreSignedPKIWithCARootsData(testCARootsData),
PRSigstoreSignedPKIWithSubjectEmail(testSubjectEmail),
PRSigstoreSignedPKIWithSubjectHostname(testSubjectHostname),
},
subjectEmail: testSubjectEmail,
subjectHostname: testSubjectHostname,
},
{
option: []PRSigstoreSignedPKIOption{
PRSigstoreSignedPKIWithCARootsPath(testCARootsPath),
PRSigstoreSignedPKIWithCAIntermediatesPath(testCAIntermediatesPath),
PRSigstoreSignedPKIWithSubjectEmail(testSubjectEmail),
PRSigstoreSignedPKIWithSubjectHostname(testSubjectHostname),
},
intermediates: true,
subjectEmail: testSubjectEmail,
subjectHostname: testSubjectHostname,
},
{
option: []PRSigstoreSignedPKIOption{
PRSigstoreSignedPKIWithCARootsPath(testCARootsPath),
PRSigstoreSignedPKIWithCAIntermediatesData(testCAIntermediatesData),
PRSigstoreSignedPKIWithSubjectEmail(testSubjectEmail),
PRSigstoreSignedPKIWithSubjectHostname(testSubjectHostname),
},
intermediates: true,
subjectEmail: testSubjectEmail,
subjectHostname: testSubjectHostname,
},
{
option: []PRSigstoreSignedPKIOption{
PRSigstoreSignedPKIWithCARootsData(testCARootsData),
PRSigstoreSignedPKIWithSubjectEmail(testSubjectEmail),
},
subjectEmail: testSubjectEmail,
},
{
option: []PRSigstoreSignedPKIOption{
PRSigstoreSignedPKIWithCARootsData(testCARootsData),
PRSigstoreSignedPKIWithSubjectHostname(testSubjectHostname),
},
subjectHostname: testSubjectHostname,
},
} {
pki, err := newPRSigstoreSignedPKI(c.option...)
require.NoError(t, err)
res, err := pki.prepareTrustRoot()
require.NoError(t, err)
assert.NotNil(t, res.caRootsCertificates)
if c.intermediates {
assert.NotNil(t, res.caIntermediateCertificates)
}
assert.Equal(t, c.subjectEmail, res.subjectEmail)
assert.Equal(t, c.subjectHostname, res.subjectHostname)
}
// Failure
for _, pki := range []prSigstoreSignedPKI{ // Use a prSigstoreSignedPKI because these configurations should be rejected by NewPRSigstoreSignedPKI.
{ // Neither CARootsPath nor CARootsData specified
SubjectEmail: testSubjectEmail,
SubjectHostname: testSubjectHostname,
},
{ // Both CARootsPath and CARootsData specified
CARootsPath: testCARootsPath,
CARootsData: testCARootsData,
SubjectEmail: testSubjectEmail,
SubjectHostname: testSubjectHostname,
},
{ // Both CAIntermediatesPath and CAIntermediatesData specified
CARootsPath: testCARootsPath,
CAIntermediatesPath: testCAIntermediatesPath,
CAIntermediatesData: testCAIntermediatesData,
SubjectEmail: testSubjectEmail,
SubjectHostname: testSubjectHostname,
},
{ // Invalid CARootsPath
CARootsPath: "fixtures/image.signature",
SubjectEmail: testSubjectEmail,
},
{ // Invalid CAIntermediatesPath
CARootsPath: testCARootsPath,
CAIntermediatesPath: "fixtures/image.signature",
SubjectEmail: testSubjectEmail,
},
{ // Unusable CARootsPath
CARootsPath: "fixtures/this/does/not/exist",
SubjectEmail: testSubjectEmail,
},
{ // Unusable CAIntermediatesPath
CARootsPath: testCARootsPath,
CAIntermediatesPath: "fixtures/this/does/not/exist",
SubjectEmail: testSubjectEmail,
},
{ // Invalid CARootsData
CARootsData: []byte("invalid"),
SubjectEmail: testSubjectEmail,
},
{ // Invalid CAIntermediatesData
CARootsData: testCARootsData,
CAIntermediatesData: []byte("invalid"),
SubjectEmail: testSubjectEmail,
},
{ // Neither SubjectEmail nor SubjectHostname specified
CARootsPath: testCARootsPath,
CAIntermediatesPath: testCAIntermediatesPath,
},
} {
_, err := pki.prepareTrustRoot()
assert.Error(t, err)
}
}
func TestPRSigstoreSignedPrepareTrustRoot(t *testing.T) {
const testKeyPath = "fixtures/cosign.pub"
const testKeyPath2 = "fixtures/cosign2.pub"
testKeyData, err := os.ReadFile(testKeyPath)
require.NoError(t, err)
testKeyData2, err := os.ReadFile(testKeyPath2)
require.NoError(t, err)
testFulcio, err := NewPRSigstoreSignedFulcio(
PRSigstoreSignedFulcioWithCAPath("fixtures/fulcio_v1.crt.pem"),
PRSigstoreSignedFulcioWithOIDCIssuer("https://github.com/login/oauth"),
PRSigstoreSignedFulcioWithSubjectEmail("mitr@redhat.com"),
)
require.NoError(t, err)
const testRekorPublicKeyPath = "fixtures/rekor.pub"
testRekorPublicKeyData, err := os.ReadFile(testRekorPublicKeyPath)
require.NoError(t, err)
testPKI, err := NewPRSigstoreSignedPKI(
PRSigstoreSignedPKIWithCARootsPath("fixtures/pki_root_crts.pem"),
PRSigstoreSignedPKIWithCAIntermediatesPath("fixtures/pki_intermediate_crts.pem"),
PRSigstoreSignedPKIWithSubjectEmail("qiwan@redhat.com"),
PRSigstoreSignedPKIWithSubjectHostname("myhost.example.com"),
)
require.NoError(t, err)
testIdentity := newPRMMatchRepoDigestOrExact()
testIdentityOption := PRSigstoreSignedWithSignedIdentity(testIdentity)
// Success with public key
for _, c := range []struct {
option PRSigstoreSignedOption
numKeys int
}{
{PRSigstoreSignedWithKeyPath(testKeyPath), 1},
{PRSigstoreSignedWithKeyPaths([]string{testKeyPath, testKeyPath2}), 2},
{PRSigstoreSignedWithKeyData(testKeyData), 1},
{PRSigstoreSignedWithKeyDatas([][]byte{testKeyData, testKeyData2}), 2},
} {
pr, err := newPRSigstoreSigned(c.option, testIdentityOption)
require.NoError(t, err)
res, err := pr.prepareTrustRoot()
require.NoError(t, err)
assert.NotNil(t, res.publicKeys)
assert.Len(t, res.publicKeys, c.numKeys)
assert.Nil(t, res.fulcio)
assert.Nil(t, res.rekorPublicKeys)
assert.Nil(t, res.pki)
}
// Success with Fulcio
pr, err := newPRSigstoreSigned(
PRSigstoreSignedWithFulcio(testFulcio),
PRSigstoreSignedWithRekorPublicKeyData(testRekorPublicKeyData),
testIdentityOption,
)
require.NoError(t, err)
res, err := pr.prepareTrustRoot()
require.NoError(t, err)
assert.Nil(t, res.publicKeys)
assert.NotNil(t, res.fulcio)
assert.Nil(t, res.pki)
assert.Len(t, res.rekorPublicKeys, 1)
// Success with Rekor public key
for _, keyOption := range []PRSigstoreSignedOption{
PRSigstoreSignedWithKeyData(testKeyData),
PRSigstoreSignedWithKeyPaths([]string{testKeyPath, testKeyPath2}),
PRSigstoreSignedWithKeyData(testKeyData),
PRSigstoreSignedWithKeyDatas([][]byte{testKeyData, testKeyData2}),
} {
for _, rekor := range []struct {
option PRSigstoreSignedOption
numKeys int
}{
{PRSigstoreSignedWithRekorPublicKeyPath(testRekorPublicKeyPath), 1},
{PRSigstoreSignedWithRekorPublicKeyPaths([]string{testRekorPublicKeyPath, testKeyPath}), 2},
{PRSigstoreSignedWithRekorPublicKeyData(testRekorPublicKeyData), 1},
{PRSigstoreSignedWithRekorPublicKeyDatas([][]byte{testRekorPublicKeyData, testKeyData}), 2},
} {
pr, err := newPRSigstoreSigned(keyOption, rekor.option, testIdentityOption)
require.NoError(t, err)
res, err := pr.prepareTrustRoot()
require.NoError(t, err)
assert.NotNil(t, res.publicKeys)
assert.Nil(t, res.fulcio)
assert.Nil(t, res.pki)
assert.Len(t, res.rekorPublicKeys, rekor.numKeys)
}
}
// Success with PKI
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithPKI(testPKI),
testIdentityOption,
)
require.NoError(t, err)
res, err = pr.prepareTrustRoot()
require.NoError(t, err)
assert.Nil(t, res.publicKeys)
assert.Nil(t, res.fulcio)
assert.Nil(t, res.rekorPublicKeys)
assert.NotNil(t, res.pki)
// Failure
for _, pr := range []prSigstoreSigned{ // Use a prSigstoreSigned because these configurations should be rejected by NewPRSigstoreSigned.
{ // Both KeyPath and KeyData specified
KeyPath: testKeyPath,
KeyData: testKeyData,
SignedIdentity: testIdentity,
},
{ // Invalid public key path
KeyPath: "fixtures/image.signature",
SignedIdentity: testIdentity,
},
{ // Unusable public key path
KeyPath: "fixtures/this/does/not/exist",
SignedIdentity: testIdentity,
},
{ // Both KeyPath and KeyPaths specified
KeyPath: testKeyPath,
KeyPaths: []string{testKeyPath, testKeyPath2},
SignedIdentity: testIdentity,
},
{ // Empty KeyPaths
KeyPaths: []string{},
SignedIdentity: testIdentity,
},
{ // Invalid KeyPaths element
KeyPaths: []string{"fixtures/image.signature", testKeyPath2},
SignedIdentity: testIdentity,
},
{
KeyPaths: []string{testKeyPath2, "fixtures/image.signature"},
SignedIdentity: testIdentity,
},
{ // Unusable KeyPaths element
KeyPaths: []string{"fixtures/this/does/not/exist", testKeyPath2},
SignedIdentity: testIdentity,
},
{
KeyPaths: []string{testKeyPath2, "fixtures/this/does/not/exist"},
SignedIdentity: testIdentity,
},
{ // Invalid public key data
KeyData: []byte("this is invalid"),
SignedIdentity: testIdentity,
},
{ // Both KeyData and KeyDatas specified
KeyData: testKeyData,
KeyDatas: [][]byte{testKeyData, testKeyData2},
SignedIdentity: testIdentity,
},
{ // Empty KeyDatas
KeyDatas: [][]byte{},
SignedIdentity: testIdentity,
},
{ // Invalid KeyDatas element
KeyDatas: [][]byte{[]byte("this is invalid"), testKeyData2},
SignedIdentity: testIdentity,
},
{
KeyDatas: [][]byte{testKeyData, []byte("this is invalid")},
SignedIdentity: testIdentity,
},
{ // Invalid Fulcio configuration
Fulcio: &prSigstoreSignedFulcio{},
RekorPublicKeyData: testKeyData,
SignedIdentity: testIdentity,
},
{ // Both RekorPublicKeyPath and RekorPublicKeyData specified
KeyData: testKeyData,
RekorPublicKeyPath: testRekorPublicKeyPath,
RekorPublicKeyData: testRekorPublicKeyData,
SignedIdentity: testIdentity,
},
{ // Invalid Rekor public key path
KeyData: testKeyData,
RekorPublicKeyPath: "fixtures/image.signature",
SignedIdentity: testIdentity,
},
{ // Both RekorPublicKeyPath and RekorPublicKeyPaths specified
KeyData: testKeyData,
RekorPublicKeyPath: testRekorPublicKeyPath,
RekorPublicKeyPaths: []string{testRekorPublicKeyPath, testKeyPath},
SignedIdentity: testIdentity,
},
{ // Empty RekorPublicKeyPaths
KeyData: testKeyData,
RekorPublicKeyPaths: []string{},
SignedIdentity: testIdentity,
},
{ // Invalid RekorPublicKeyPaths
KeyData: testKeyData,
RekorPublicKeyPaths: []string{"fixtures/image.signature", testRekorPublicKeyPath},
SignedIdentity: testIdentity,
},
{ // Invalid RekorPublicKeyPaths
KeyData: testKeyData,
RekorPublicKeyPaths: []string{testRekorPublicKeyPath, "fixtures/image.signature"},
SignedIdentity: testIdentity,
},
{ // Invalid Rekor public key data
KeyData: testKeyData,
RekorPublicKeyData: []byte("this is invalid"),
SignedIdentity: testIdentity,
},
{ // Both RekorPublicKeyData and RekorPublicKeyDatas specified
KeyData: testKeyData,
RekorPublicKeyData: testRekorPublicKeyData,
RekorPublicKeyDatas: [][]byte{testRekorPublicKeyData, testKeyData},
SignedIdentity: testIdentity,
},
{ // Empty RekorPublicKeyDatas
KeyData: testKeyData,
RekorPublicKeyDatas: [][]byte{},
SignedIdentity: testIdentity,
},
{ // Invalid RekorPublicKeyDatas
KeyData: testKeyData,
RekorPublicKeyDatas: [][]byte{[]byte("this is invalid"), testRekorPublicKeyData},
SignedIdentity: testIdentity,
},
{
KeyData: testKeyData,
RekorPublicKeyDatas: [][]byte{testRekorPublicKeyData, []byte("this is invalid")},
SignedIdentity: testIdentity,
},
{ // Rekor public key is not ECDSA
KeyData: testKeyData,
RekorPublicKeyPath: "fixtures/some-rsa-key.pub",
SignedIdentity: testIdentity,
},
{ // Invalid PKI configuration
PKI: &prSigstoreSignedPKI{},
SignedIdentity: testIdentity,
},
} {
_, err = pr.prepareTrustRoot()
assert.Error(t, err)
}
}
func TestPRSigstoreSignedIsSignatureAuthorAccepted(t *testing.T) {
// Currently, this fails even with a correctly signed image.
prm := NewPRMMatchRepository() // We prefer to test with a Cosign-created signature for interoperability, and that doesnt work with matchExact.
testImage := dirImageMock(t, "fixtures/dir-img-cosign-valid", "192.168.64.2:5000/cosign-signed-single-sample")
testImageSigBlob, err := os.ReadFile("fixtures/dir-img-cosign-valid/signature-1")
require.NoError(t, err)
// Successful validation, with KeyData and KeyPath
pr, err := newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, parsedSig, err := pr.isSignatureAuthorAccepted(context.Background(), testImage, testImageSigBlob)
assertSARRejected(t, sar, parsedSig, err)
}
// sigstoreSignatureFromFile returns a signature.Sigstore loaded from path.
func sigstoreSignatureFromFile(t *testing.T, path string) signature.Sigstore {
blob, err := os.ReadFile(path)
require.NoError(t, err)
genericSig, err := signature.FromBlob(blob)
require.NoError(t, err)
sig, ok := genericSig.(signature.Sigstore)
require.True(t, ok)
return sig
}
// sigstoreSignatureWithoutAnnotation returns a signature.Sigstore based on template
// that is missing the specified annotation.
func sigstoreSignatureWithoutAnnotation(t *testing.T, template signature.Sigstore, annotation string) signature.Sigstore {
annotations := template.UntrustedAnnotations() // This returns a copy that is safe to modify.
require.Contains(t, annotations, annotation)
delete(annotations, annotation)
return signature.SigstoreFromComponents(template.UntrustedMIMEType(), template.UntrustedPayload(), annotations)
}
// sigstoreSignatureWithModifiedAnnotation returns a signature.Sigstore based on template
// where the specified annotation is replaced
func sigstoreSignatureWithModifiedAnnotation(template signature.Sigstore, annotation, value string) signature.Sigstore {
annotations := template.UntrustedAnnotations() // This returns a copy that is safe to modify.
annotations[annotation] = value
return signature.SigstoreFromComponents(template.UntrustedMIMEType(), template.UntrustedPayload(), annotations)
}
func TestPRrSigstoreSignedIsSignatureAccepted(t *testing.T) {
assertAccepted := func(sar signatureAcceptanceResult, err error) {
assert.Equal(t, sarAccepted, sar)
assert.NoError(t, err)
}
assertRejected := func(sar signatureAcceptanceResult, err error) {
logrus.Errorf("%v", err)
assert.Equal(t, sarRejected, sar)
assert.Error(t, err)
}
prm := NewPRMMatchRepository() // We prefer to test with a Cosign-created signature to ensure interoperability, and that doesnt work with matchExact. matchExact is tested later.
testKeyImage := dirImageMock(t, "fixtures/dir-img-cosign-valid", "192.168.64.2:5000/cosign-signed-single-sample")
testKeyImageSig := sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-valid/signature-1")
testKeyRekorImage := dirImageMock(t, "fixtures/dir-img-cosign-key-rekor-valid", "192.168.64.2:5000/cosign-signed/key-1")
testKeyRekorImageSig := sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-key-rekor-valid/signature-1")
testFulcioRekorImage := dirImageMock(t, "fixtures/dir-img-cosign-fulcio-rekor-valid", "192.168.64.2:5000/cosign-signed/fulcio-rekor-1")
testFulcioRekorImageSig := sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-fulcio-rekor-valid/signature-1")
testPKIImage := dirImageMock(t, "fixtures/dir-img-cosign-pki-valid", "localhost:5000/test")
testPKIImageSig := sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-pki-valid/signature-1")
keyData, err := os.ReadFile("fixtures/cosign.pub")
require.NoError(t, err)
keyData2, err := os.ReadFile("fixtures/cosign2.pub")
require.NoError(t, err)
// prepareTrustRoot fails
pr := &prSigstoreSigned{
KeyPath: "fixtures/cosign.pub",
KeyData: keyData,
SignedIdentity: prm,
}
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err := pr.isSignatureAccepted(context.Background(), nil, testKeyImageSig)
assertRejected(sar, err)
// Signature has no cryptographic signature
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
signature.SigstoreFromComponents(testKeyImageSig.UntrustedMIMEType(), testKeyImageSig.UntrustedPayload(), nil))
assertRejected(sar, err)
// None of the public key, Fulcio, or PKI is specified
pr = &prSigstoreSigned{
SignedIdentity: prm,
}
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil, testKeyImageSig)
assertRejected(sar, err)
// Both a public key and Fulcio is specified
fulcio, err := NewPRSigstoreSignedFulcio(
PRSigstoreSignedFulcioWithCAPath("fixtures/fulcio_v1.crt.pem"),
PRSigstoreSignedFulcioWithOIDCIssuer("https://github.com/login/oauth"),
PRSigstoreSignedFulcioWithSubjectEmail("mitr@redhat.com"),
)
require.NoError(t, err)
pr = &prSigstoreSigned{
KeyPath: "fixtures/cosign.pub",
Fulcio: fulcio,
SignedIdentity: prm,
}
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil, testKeyImageSig)
assertRejected(sar, err)
// Both Fulcio and PKI is specified
pki, err := NewPRSigstoreSignedPKI(
PRSigstoreSignedPKIWithCARootsPath("fixtures/pki_root_crts.pem"),
PRSigstoreSignedPKIWithCAIntermediatesPath("fixtures/pki_intermediate_crts.pem"),
PRSigstoreSignedPKIWithSubjectEmail("qiwan@redhat.com"),
)
require.NoError(t, err)
pr = &prSigstoreSigned{
Fulcio: fulcio,
PKI: pki,
SignedIdentity: prm,
}
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil, testKeyImageSig)
assertRejected(sar, err)
// Both PKI and Rekor public key is specified
pr = &prSigstoreSigned{
PKI: pki,
RekorPublicKeyPath: "fixtures/rekor.pub",
SignedIdentity: prm,
}
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil, testKeyImageSig)
assertRejected(sar, err)
// Successful key+Rekor use
for _, keyPaths := range [][]string{
{"fixtures/cosign2.pub"},
{"fixtures/cosign2.pub", "fixtures/cosign.pub"},
{"fixtures/cosign.pub", "fixtures/cosign2.pub"},
} {
for _, rekorKeyPaths := range [][]string{
{"fixtures/rekor.pub"},
{"fixtures/rekor.pub", "fixtures/cosign.pub"},
{"fixtures/cosign.pub", "fixtures/rekor.pub"},
} {
pr, err := newPRSigstoreSigned(
PRSigstoreSignedWithKeyPaths(keyPaths),
PRSigstoreSignedWithRekorPublicKeyPaths(rekorKeyPaths),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err := pr.isSignatureAccepted(context.Background(), testKeyRekorImage, testKeyRekorImageSig)
require.NoError(t, err)
assertAccepted(sar, err)
}
}
// key+Rekor, missing Rekor SET annotation
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign2.pub"),
PRSigstoreSignedWithRekorPublicKeyPath("fixtures/rekor.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testKeyRekorImageSig, signature.SigstoreSETAnnotationKey))
assertRejected(sar, err)
// Actual Rekor logic is unit-tested elsewhere, but smoke-test the basics:
// key+Rekor: Invalid Rekor SET
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithModifiedAnnotation(testKeyRekorImageSig, signature.SigstoreSETAnnotationKey,
"this is not a valid SET"))
assertRejected(sar, err)
// key+Rekor: A Rekor SET which we dont accept (one of many reasons)
for _, keyPaths := range [][]string{
{"fixtures/cosign2.pub"},
{"fixtures/cosign2.pub", "fixtures/cosign.pub"},
{"fixtures/cosign.pub", "fixtures/cosign2.pub"},
} {
pr, err := newPRSigstoreSigned(
PRSigstoreSignedWithKeyPaths(keyPaths),
PRSigstoreSignedWithRekorPublicKeyPath("fixtures/cosign.pub"), // not rekor.pub = a key mismatch
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil, testKeyRekorImageSig)
assertRejected(sar, err)
}
// key+Rekor: A valid Rekor SET for one accepted key, but a signature with a _different_ accepted key
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPaths([]string{"fixtures/cosign.pub", "fixtures/cosign2.pub"}),
PRSigstoreSignedWithRekorPublicKeyPath("fixtures/rekor.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
// testKeyImageSig is signed by cosign.pub; the SET contains cosign2.pub.
// The SET includes the signature contents… so this actually fails on "signature in Rekor SET does not match"
// rather than accepting the SET and later failing to validate payload; wed need a way to generate the same signature
// using two different private keys.
sar, err = pr.isSignatureAccepted(context.Background(), nil, sigstoreSignatureWithModifiedAnnotation(testKeyImageSig,
signature.SigstoreSETAnnotationKey, testKeyRekorImageSig.UntrustedAnnotations()[signature.SigstoreSETAnnotationKey]))
assertRejected(sar, err)
// Successful Fulcio certificate use
fulcio, err = NewPRSigstoreSignedFulcio(
PRSigstoreSignedFulcioWithCAPath("fixtures/fulcio_v1.crt.pem"),
PRSigstoreSignedFulcioWithOIDCIssuer("https://github.com/login/oauth"),
PRSigstoreSignedFulcioWithSubjectEmail("mitr@redhat.com"),
)
require.NoError(t, err)
for _, rekorKeyPaths := range [][]string{
{"fixtures/rekor.pub"},
{"fixtures/rekor.pub", "fixtures/cosign.pub"},
{"fixtures/cosign.pub", "fixtures/rekor.pub"},
} {
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithFulcio(fulcio),
PRSigstoreSignedWithRekorPublicKeyPaths(rekorKeyPaths),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), testFulcioRekorImage,
testFulcioRekorImageSig)
assertAccepted(sar, err)
}
// Fulcio, no Rekor requirement
pr2 := &prSigstoreSigned{
Fulcio: fulcio,
SignedIdentity: prm,
}
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr2.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testFulcioRekorImageSig, signature.SigstoreSETAnnotationKey))
assertRejected(sar, err)
// Fulcio, missing Rekor SET annotation
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testFulcioRekorImageSig, signature.SigstoreSETAnnotationKey))
assertRejected(sar, err)
// Fulcio, missing certificate annotation
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testFulcioRekorImageSig, signature.SigstoreCertificateAnnotationKey))
assertRejected(sar, err)
// Fulcio: missing certificate chain annotation causes the Cosign-issued signature to be rejected
// because there is no path to the trusted CA
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testFulcioRekorImageSig, signature.SigstoreIntermediateCertificateChainAnnotationKey))
assertRejected(sar, err)
// … but a signature without the intermediate annotation is fine if the issuer is directly trusted
// (which we handle by trusting the intermediates)
fulcio2, err := NewPRSigstoreSignedFulcio(
PRSigstoreSignedFulcioWithCAData([]byte(testFulcioRekorImageSig.UntrustedAnnotations()[signature.SigstoreIntermediateCertificateChainAnnotationKey])),
PRSigstoreSignedFulcioWithOIDCIssuer("https://github.com/login/oauth"),
PRSigstoreSignedFulcioWithSubjectEmail("mitr@redhat.com"),
)
require.NoError(t, err)
pr2, err = newPRSigstoreSigned(
PRSigstoreSignedWithFulcio(fulcio2),
PRSigstoreSignedWithRekorPublicKeyPath("fixtures/rekor.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr2.isSignatureAccepted(context.Background(), testFulcioRekorImage,
sigstoreSignatureWithoutAnnotation(t, testFulcioRekorImageSig, signature.SigstoreIntermediateCertificateChainAnnotationKey))
assertAccepted(sar, err)
// Actual Fulcio and Rekor logic is unit-tested elsewhere, but smoke-test the basics:
// Fulcio: Invalid Fulcio certificate
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithModifiedAnnotation(testFulcioRekorImageSig, signature.SigstoreCertificateAnnotationKey,
"this is not a valid certificate"))
assertRejected(sar, err)
// Fulcio: A Fulcio certificate which we dont accept (one of many reasons)
fulcio2, err = NewPRSigstoreSignedFulcio(
PRSigstoreSignedFulcioWithCAPath("fixtures/fulcio_v1.crt.pem"),
PRSigstoreSignedFulcioWithOIDCIssuer("https://github.com/login/oauth"),
PRSigstoreSignedFulcioWithSubjectEmail("this-does-not-match@example.com"),
)
require.NoError(t, err)
pr2, err = newPRSigstoreSigned(
PRSigstoreSignedWithFulcio(fulcio2),
PRSigstoreSignedWithRekorPublicKeyPath("fixtures/rekor.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr2.isSignatureAccepted(context.Background(), nil, testFulcioRekorImageSig)
assertRejected(sar, err)
// Fulcio: Invalid Rekor SET
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithModifiedAnnotation(testFulcioRekorImageSig, signature.SigstoreSETAnnotationKey,
"this is not a valid SET"))
assertRejected(sar, err)
// Fulcio: A Rekor SET which we dont accept (one of many reasons)
pr2, err = newPRSigstoreSigned(
PRSigstoreSignedWithFulcio(fulcio),
PRSigstoreSignedWithRekorPublicKeyPath("fixtures/cosign.pub"), // not rekor.pub = a key mismatch
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr2.isSignatureAccepted(context.Background(), nil, testFulcioRekorImageSig)
assertRejected(sar, err)
// Successful PKI certificate use
pki, err = NewPRSigstoreSignedPKI(
PRSigstoreSignedPKIWithCARootsPath("fixtures/pki_root_crts.pem"),
PRSigstoreSignedPKIWithCAIntermediatesPath("fixtures/pki_intermediate_crts.pem"),
PRSigstoreSignedPKIWithSubjectEmail("qiwan@redhat.com"),
PRSigstoreSignedPKIWithSubjectHostname("myhost.example.com"),
)
require.NoError(t, err)
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithPKI(pki),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), testPKIImage, testPKIImageSig)
assertAccepted(sar, err)
// PKI, missing certificate annotation causes the Cosign-issued signature to be rejected
sar, err = pr.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testPKIImageSig, signature.SigstoreCertificateAnnotationKey))
assertRejected(sar, err)
// PKI, missing certificate chain annotation is fine if the issuer is directly trusted
sar, err = pr.isSignatureAccepted(context.Background(), testPKIImage,
sigstoreSignatureWithoutAnnotation(t, testPKIImageSig, signature.SigstoreIntermediateCertificateChainAnnotationKey))
assertAccepted(sar, err)
// PKI, missing certificate chain annotation causes the Cosign-issued signature to be rejected
pki2, err := NewPRSigstoreSignedPKI(
PRSigstoreSignedPKIWithCARootsPath("fixtures/pki_root_crts.pem"),
PRSigstoreSignedPKIWithSubjectEmail("qiwan@redhat.com"),
PRSigstoreSignedPKIWithSubjectHostname("myhost.example.com"),
)
require.NoError(t, err)
pr2, err = newPRSigstoreSigned(
PRSigstoreSignedWithPKI(pki2),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr2.isSignatureAccepted(context.Background(), nil,
sigstoreSignatureWithoutAnnotation(t, testPKIImageSig, signature.SigstoreIntermediateCertificateChainAnnotationKey))
assertRejected(sar, err)
// Successful validation, with KeyPath/KeyPaths/KeyData/KeyDatas
for _, opt := range []PRSigstoreSignedOption{
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithKeyPaths([]string{"fixtures/cosign.pub", "fixtures/cosign2.pub"}),
PRSigstoreSignedWithKeyPaths([]string{"fixtures/cosign2.pub", "fixtures/cosign.pub"}),
PRSigstoreSignedWithKeyData(keyData),
PRSigstoreSignedWithKeyDatas([][]byte{keyData, keyData2}),
PRSigstoreSignedWithKeyDatas([][]byte{keyData2, keyData}),
} {
pr, err := newPRSigstoreSigned(
opt,
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), testKeyImage, testKeyImageSig)
assertAccepted(sar, err)
}
// A signature which does not verify
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil,
signature.SigstoreFromComponents(testKeyImageSig.UntrustedMIMEType(), testKeyImageSig.UntrustedPayload(), map[string]string{
signature.SigstoreSignatureAnnotationKey: base64.StdEncoding.EncodeToString([]byte("invalid signature")),
}))
assertRejected(sar, err)
// A valid signature using an unknown key.
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
// Pass a nil pointer to, kind of, test that the return value does not depend on the image.
sar, err = pr.isSignatureAccepted(context.Background(), nil, sigstoreSignatureFromFile(t, "fixtures/unknown-cosign-key.signature"))
assertRejected(sar, err)
// A valid signature with a rejected identity.
nonmatchingPRM, err := NewPRMExactReference("this/does-not:match")
require.NoError(t, err)
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(nonmatchingPRM),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), testKeyImage, testKeyImageSig)
assertRejected(sar, err)
// Error reading image manifest
image := dirImageMock(t, "fixtures/dir-img-cosign-no-manifest", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), image, sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-no-manifest/signature-1"))
assertRejected(sar, err)
// Error computing manifest digest
image = dirImageMock(t, "fixtures/dir-img-cosign-manifest-digest-error", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), image, sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-manifest-digest-error/signature-1"))
assertRejected(sar, err)
// A valid signature with a non-matching manifest
image = dirImageMock(t, "fixtures/dir-img-cosign-modified-manifest", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), image, sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-modified-manifest/signature-1"))
assertRejected(sar, err)
// Minimally check that the prmMatchExact also works as expected:
// - Signatures with a matching tag work
image = dirImageMock(t, "fixtures/dir-img-cosign-valid-with-tag", "192.168.64.2:5000/skopeo-signed:tag")
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(NewPRMMatchExact()),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), image, sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-valid-with-tag/signature-1"))
assertAccepted(sar, err)
// - Signatures with a non-matching tag are rejected
image = dirImageMock(t, "fixtures/dir-img-cosign-valid-with-tag", "192.168.64.2:5000/skopeo-signed:othertag")
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(NewPRMMatchExact()),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), image, sigstoreSignatureFromFile(t, "fixtures/dir-img-cosign-valid-with-tag/signature-1"))
assertRejected(sar, err)
// - Cosign-created signatures are rejected
pr, err = newPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(NewPRMMatchExact()),
)
require.NoError(t, err)
sar, err = pr.isSignatureAccepted(context.Background(), testKeyImage, testKeyImageSig)
assertRejected(sar, err)
}
func TestPRSigstoreSignedIsRunningImageAllowed(t *testing.T) {
prm := NewPRMMatchRepository() // We prefer to test with a Cosign-created signature to ensure interoperability, and that doesnt work with matchExact. matchExact is tested later.
// A simple success case: single valid signature.
image := dirImageMock(t, "fixtures/dir-img-cosign-valid", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err := NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err := pr.isRunningImageAllowed(context.Background(), image)
assertRunningAllowed(t, allowed, err)
// Error reading signatures
invalidSigDir := createInvalidSigDir(t)
image = dirImageMock(t, invalidSigDir, "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejected(t, allowed, err)
// No signatures
image = dirImageMock(t, "fixtures/dir-img-unsigned", "testing/manifest:latest")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejected(t, allowed, err)
// Only non-sigstore signatures
image = dirImageMock(t, "fixtures/dir-img-valid", "testing/manifest:latest")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejected(t, allowed, err)
// Only non-signature sigstore attachments
image = dirImageMock(t, "fixtures/dir-img-cosign-other-attachment", "testing/manifest:latest")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejected(t, allowed, err)
// 1 invalid signature: use dir-img-valid, but a non-matching Docker reference
image = dirImageMock(t, "fixtures/dir-img-cosign-valid", "testing/manifest:notlatest")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejectedPolicyRequirement(t, allowed, err)
// 2 valid signatures
image = dirImageMock(t, "fixtures/dir-img-cosign-valid-2", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningAllowed(t, allowed, err)
// One invalid, one valid signature (in this order)
image = dirImageMock(t, "fixtures/dir-img-cosign-mixed", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningAllowed(t, allowed, err)
// 2 invalid signajtures: use dir-img-cosign-valid-2, but a non-matching Docker reference
image = dirImageMock(t, "fixtures/dir-img-cosign-valid-2", "this/does-not:match")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(prm),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejectedPolicyRequirement(t, allowed, err)
// Minimally check that the prmMatchExact also works as expected:
// - Signatures with a matching tag work
image = dirImageMock(t, "fixtures/dir-img-cosign-valid-with-tag", "192.168.64.2:5000/skopeo-signed:tag")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(NewPRMMatchExact()),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningAllowed(t, allowed, err)
// - Signatures with a non-matching tag are rejected
image = dirImageMock(t, "fixtures/dir-img-cosign-valid-with-tag", "192.168.64.2:5000/skopeo-signed:othertag")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(NewPRMMatchExact()),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejectedPolicyRequirement(t, allowed, err)
// - Cosign-created signatures are rejected
image = dirImageMock(t, "fixtures/dir-img-cosign-valid", "192.168.64.2:5000/cosign-signed-single-sample")
pr, err = NewPRSigstoreSigned(
PRSigstoreSignedWithKeyPath("fixtures/cosign.pub"),
PRSigstoreSignedWithSignedIdentity(NewPRMMatchExact()),
)
require.NoError(t, err)
allowed, err = pr.isRunningImageAllowed(context.Background(), image)
assertRunningRejectedPolicyRequirement(t, allowed, err)
}