Merge branch 'main' into dependabot/go_modules/github.com/containerd/containerd/v2-2.0.0-rc.5
This commit is contained in:
@@ -316,8 +316,8 @@ func buildImageFromLayers(layers []*Layer, manifest *v1.Descriptor, subject *v1.
|
|||||||
return newImg, nil
|
return newImg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtractEnvelopes(manifest *Manifest, predicateType string) ([]*Envelope, error) {
|
func ExtractEnvelopes(manifest *Manifest, predicateType string) ([]*EnvelopeReference, error) {
|
||||||
var envs []*Envelope
|
var envs []*EnvelopeReference
|
||||||
dsseMediaType, err := DSSEMediaType(predicateType)
|
dsseMediaType, err := DSSEMediaType(predicateType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get DSSE media type for predicate '%s': %w", predicateType, err)
|
return nil, fmt.Errorf("failed to get DSSE media type for predicate '%s': %w", predicateType, err)
|
||||||
@@ -333,11 +333,20 @@ func ExtractEnvelopes(manifest *Manifest, predicateType string) ([]*Envelope, er
|
|||||||
return nil, fmt.Errorf("failed to get layer contents: %w", err)
|
return nil, fmt.Errorf("failed to get layer contents: %w", err)
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
env := new(Envelope)
|
env := new(EnvelopeReference)
|
||||||
err = json.NewDecoder(reader).Decode(&env)
|
err = json.NewDecoder(reader).Decode(&env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to decode envelope: %w", err)
|
return nil, fmt.Errorf("failed to decode envelope: %w", err)
|
||||||
}
|
}
|
||||||
|
var uri string
|
||||||
|
if len(manifest.OriginalDescriptor.URLs) > 0 {
|
||||||
|
uri = manifest.OriginalDescriptor.URLs[0]
|
||||||
|
}
|
||||||
|
env.ResourceDescriptor = &ResourceDescriptor{
|
||||||
|
MediaType: string(mt),
|
||||||
|
Digest: map[string]string{manifest.OriginalDescriptor.Digest.Algorithm: manifest.OriginalDescriptor.Digest.Hex},
|
||||||
|
URI: uri,
|
||||||
|
}
|
||||||
envs = append(envs, env)
|
envs = append(envs, env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ func (r *LayoutResolver) fetchManifest() (*Manifest, error) {
|
|||||||
return r.Manifest, nil
|
return r.Manifest, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LayoutResolver) Attestations(_ context.Context, predicateType string) ([]*Envelope, error) {
|
func (r *LayoutResolver) Attestations(_ context.Context, predicateType string) ([]*EnvelopeReference, error) {
|
||||||
var envs []*Envelope
|
var envs []*EnvelopeReference
|
||||||
dsseMediaType, err := DSSEMediaType(predicateType)
|
dsseMediaType, err := DSSEMediaType(predicateType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get DSSE media type for predicate '%s': %w", predicateType, err)
|
return nil, fmt.Errorf("failed to get DSSE media type for predicate '%s': %w", predicateType, err)
|
||||||
@@ -60,17 +60,26 @@ func (r *LayoutResolver) Attestations(_ context.Context, predicateType string) (
|
|||||||
if mts != dsseMediaType {
|
if mts != dsseMediaType {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
env := new(Envelope)
|
env := new(EnvelopeReference)
|
||||||
// parse layer blob as json
|
// parse layer blob as json
|
||||||
r, err := attestationLayer.Layer.Uncompressed()
|
layer, err := attestationLayer.Layer.Uncompressed()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get layer contents: %w", err)
|
return nil, fmt.Errorf("failed to get layer contents: %w", err)
|
||||||
}
|
}
|
||||||
defer r.Close()
|
defer layer.Close()
|
||||||
err = json.NewDecoder(r).Decode(env)
|
err = json.NewDecoder(layer).Decode(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to decode envelope: %w", err)
|
return nil, fmt.Errorf("failed to decode envelope: %w", err)
|
||||||
}
|
}
|
||||||
|
var uri string
|
||||||
|
if len(r.Manifest.OriginalDescriptor.URLs) > 0 {
|
||||||
|
uri = r.Manifest.OriginalDescriptor.URLs[0]
|
||||||
|
}
|
||||||
|
env.ResourceDescriptor = &ResourceDescriptor{
|
||||||
|
MediaType: string(mt),
|
||||||
|
Digest: map[string]string{r.Manifest.OriginalDescriptor.Digest.Algorithm: r.Manifest.OriginalDescriptor.Digest.Hex},
|
||||||
|
URI: uri,
|
||||||
|
}
|
||||||
envs = append(envs, env)
|
envs = append(envs, env)
|
||||||
}
|
}
|
||||||
return envs, nil
|
return envs, nil
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ import (
|
|||||||
var _ oci.ImageDetailsResolver = MockResolver{}
|
var _ oci.ImageDetailsResolver = MockResolver{}
|
||||||
|
|
||||||
type MockResolver struct {
|
type MockResolver struct {
|
||||||
Envs []*Envelope
|
Envs []*EnvelopeReference
|
||||||
Image string
|
Image string
|
||||||
PlatformFn func() (*v1.Platform, error)
|
PlatformFn func() (*v1.Platform, error)
|
||||||
DescriptorFn func() (*v1.Descriptor, error)
|
DescriptorFn func() (*v1.Descriptor, error)
|
||||||
ImangeNameFn func() (string, error)
|
ImangeNameFn func() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r MockResolver) Attestations(_ context.Context, _ string) ([]*Envelope, error) {
|
func (r MockResolver) Attestations(_ context.Context, _ string) ([]*EnvelopeReference, error) {
|
||||||
return r.Envs, nil
|
return r.Envs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,12 +109,12 @@ func (r *ReferrersResolver) resolveAttestations(ctx context.Context, predicateTy
|
|||||||
return aManifests, nil
|
return aManifests, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReferrersResolver) Attestations(ctx context.Context, predicateType string) ([]*Envelope, error) {
|
func (r *ReferrersResolver) Attestations(ctx context.Context, predicateType string) ([]*EnvelopeReference, error) {
|
||||||
manifests, err := r.resolveAttestations(ctx, predicateType)
|
manifests, err := r.resolveAttestations(ctx, predicateType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to resolve attestations: %w", err)
|
return nil, fmt.Errorf("failed to resolve attestations: %w", err)
|
||||||
}
|
}
|
||||||
var envs []*Envelope
|
var envs []*EnvelopeReference
|
||||||
for _, attest := range manifests {
|
for _, attest := range manifests {
|
||||||
es, err := ExtractEnvelopes(attest, predicateType)
|
es, err := ExtractEnvelopes(attest, predicateType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func NewRegistryResolver(src *oci.RegistryImageDetailsResolver) (*RegistryResolv
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RegistryResolver) Attestations(ctx context.Context, predicateType string) ([]*Envelope, error) {
|
func (r *RegistryResolver) Attestations(ctx context.Context, predicateType string) ([]*EnvelopeReference, error) {
|
||||||
if r.Manifest == nil {
|
if r.Manifest == nil {
|
||||||
attest, err := FetchManifest(ctx, r.Identifier, r.ImageSpec.Platform)
|
attest, err := FetchManifest(ctx, r.Identifier, r.ImageSpec.Platform)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ import (
|
|||||||
|
|
||||||
type Resolver interface {
|
type Resolver interface {
|
||||||
oci.ImageDetailsResolver
|
oci.ImageDetailsResolver
|
||||||
Attestations(ctx context.Context, mediaType string) ([]*Envelope, error)
|
Attestations(ctx context.Context, mediaType string) ([]*EnvelopeReference, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,17 @@ type Extension struct {
|
|||||||
Ext *DockerDSSEExtension `json:"ext"`
|
Ext *DockerDSSEExtension `json:"ext"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EnvelopeReference struct {
|
||||||
|
*Envelope
|
||||||
|
ResourceDescriptor *ResourceDescriptor `json:"resourceDescriptor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResourceDescriptor struct {
|
||||||
|
MediaType string `json:"mediaType"`
|
||||||
|
Digest map[string]string `json:"digest"`
|
||||||
|
URI string `json:"uri,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type AnnotatedStatement struct {
|
type AnnotatedStatement struct {
|
||||||
OCIDescriptor *v1.Descriptor
|
OCIDescriptor *v1.Descriptor
|
||||||
InTotoStatement *intoto.Statement
|
InTotoStatement *intoto.Statement
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type VSAPredicate struct {
|
type VSAPredicate struct {
|
||||||
Verifier VSAVerifier `json:"verifier"`
|
Verifier VSAVerifier `json:"verifier"`
|
||||||
TimeVerified string `json:"timeVerified"`
|
TimeVerified string `json:"timeVerified"`
|
||||||
ResourceURI string `json:"resourceUri"`
|
ResourceURI string `json:"resourceUri"`
|
||||||
Policy VSAPolicy `json:"policy"`
|
Policy VSAPolicy `json:"policy"`
|
||||||
InputAttestations []VSAInputAttestation `json:"inputAttestations,omitempty"`
|
InputAttestations []ResourceDescriptor `json:"inputAttestations,omitempty"`
|
||||||
VerificationResult string `json:"verificationResult"`
|
VerificationResult string `json:"verificationResult"`
|
||||||
VerifiedLevels []string `json:"verifiedLevels"`
|
VerifiedLevels []string `json:"verifiedLevels"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VSAVerifier struct {
|
type VSAVerifier struct {
|
||||||
@@ -31,11 +31,6 @@ type VSAPolicy struct {
|
|||||||
DownloadLocation string `json:"downloadLocation,omitempty"`
|
DownloadLocation string `json:"downloadLocation,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VSAInputAttestation struct {
|
|
||||||
Digest map[string]string `json:"digest"`
|
|
||||||
MediaType string `json:"mediaType"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToVSAResourceURI(sub intoto.Subject) (string, error) {
|
func ToVSAResourceURI(sub intoto.Subject) (string, error) {
|
||||||
// parse purl
|
// parse purl
|
||||||
purl, err := packageurl.FromString(sub.Name)
|
purl, err := packageurl.FromString(sub.Name)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -24,7 +24,7 @@ require (
|
|||||||
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9
|
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9
|
||||||
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9
|
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/theupdateframework/go-tuf/v2 v2.0.1
|
github.com/theupdateframework/go-tuf/v2 v2.0.2
|
||||||
google.golang.org/api v0.199.0
|
google.golang.org/api v0.199.0
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.4.0
|
||||||
)
|
)
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -581,8 +581,8 @@ github.com/thales-e-security/pool v0.0.2 h1:RAPs4q2EbWsTit6tpzuvTFlgFRJ3S8Evf5gt
|
|||||||
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
|
github.com/thales-e-security/pool v0.0.2/go.mod h1:qtpMm2+thHtqhLzTwgDBj/OuNnMpupY8mv0Phz0gjhU=
|
||||||
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
|
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
|
||||||
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
|
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
|
||||||
github.com/theupdateframework/go-tuf/v2 v2.0.1 h1:11p9tXpq10KQEujxjcIjDSivMKCMLguls7erXHZnxJQ=
|
github.com/theupdateframework/go-tuf/v2 v2.0.2 h1:PyNnjV9BJNzN1ZE6BcWK+5JbF+if370jjzO84SS+Ebo=
|
||||||
github.com/theupdateframework/go-tuf/v2 v2.0.1/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
|
github.com/theupdateframework/go-tuf/v2 v2.0.2/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
|
||||||
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadAttestation(t *testing.T, path string) *attestation.Envelope {
|
func loadAttestation(t *testing.T, path string) *attestation.EnvelopeReference {
|
||||||
ex, err := os.ReadFile(path)
|
ex, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
env := new(attestation.Envelope)
|
env := new(attestation.EnvelopeReference)
|
||||||
err = json.Unmarshal(ex, env)
|
err = json.Unmarshal(ex, env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -44,7 +44,7 @@ func TestRegoEvaluator_Evaluate(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
re := policy.NewRegoEvaluator(true, verifier)
|
re := policy.NewRegoEvaluator(true, verifier)
|
||||||
defaultResolver := attestation.MockResolver{
|
defaultResolver := attestation.MockResolver{
|
||||||
Envs: []*attestation.Envelope{loadAttestation(t, ExampleAttestation)},
|
Envs: []*attestation.EnvelopeReference{loadAttestation(t, ExampleAttestation)},
|
||||||
}
|
}
|
||||||
defaultPlatform, err := v1.ParsePlatform("linux/amd64")
|
defaultPlatform, err := v1.ParsePlatform("linux/amd64")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -122,7 +122,7 @@ func TestLoadingMappings(t *testing.T) {
|
|||||||
|
|
||||||
func TestCreateAttestationResolver(t *testing.T) {
|
func TestCreateAttestationResolver(t *testing.T) {
|
||||||
mockResolver := attestation.MockResolver{
|
mockResolver := attestation.MockResolver{
|
||||||
Envs: []*attestation.Envelope{},
|
Envs: []*attestation.EnvelopeReference{},
|
||||||
}
|
}
|
||||||
layoutResolver := &attestation.LayoutResolver{}
|
layoutResolver := &attestation.LayoutResolver{}
|
||||||
registryResolver := &oci.RegistryImageDetailsResolver{}
|
registryResolver := &oci.RegistryImageDetailsResolver{}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ func (r *NullAttestationResolver) ImageDescriptor(_ context.Context) (*v1.Descri
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *NullAttestationResolver) Attestations(_ context.Context, _ string) ([]*attestation.Envelope, error) {
|
func (r *NullAttestationResolver) Attestations(_ context.Context, _ string) ([]*attestation.EnvelopeReference, error) {
|
||||||
r.called = true
|
r.called = true
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Summary struct {
|
type Summary struct {
|
||||||
Subjects []intoto.Subject `json:"subjects"`
|
Subjects []intoto.Subject `json:"subjects"`
|
||||||
SLSALevels []string `json:"slsa_levels"`
|
Inputs []attestation.ResourceDescriptor `json:"input_attestations"`
|
||||||
Verifier string `json:"verifier"`
|
SLSALevels []string `json:"slsa_levels"`
|
||||||
PolicyURI string `json:"policy_uri"`
|
Verifier string `json:"verifier"`
|
||||||
|
PolicyURI string `json:"policy_uri"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Violation struct {
|
type Violation struct {
|
||||||
|
|||||||
6
test/testdata/local-policy-pass/policy.rego
vendored
6
test/testdata/local-policy-pass/policy.rego
vendored
@@ -37,11 +37,17 @@ subjects contains subject if {
|
|||||||
some subject in statement.subject
|
some subject in statement.subject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inputs contains desc if {
|
||||||
|
some att in atts
|
||||||
|
desc := att.resourceDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
result := {
|
result := {
|
||||||
"success": true,
|
"success": true,
|
||||||
"violations": set(),
|
"violations": set(),
|
||||||
"summary": {
|
"summary": {
|
||||||
"subjects": subjects,
|
"subjects": subjects,
|
||||||
|
"input_attestations": inputs,
|
||||||
"slsa_levels": ["SLSA_BUILD_LEVEL_3"],
|
"slsa_levels": ["SLSA_BUILD_LEVEL_3"],
|
||||||
"verifier": "docker-official-images",
|
"verifier": "docker-official-images",
|
||||||
"policy_uri": "https://docker.com/official/policy/v0.1",
|
"policy_uri": "https://docker.com/official/policy/v0.1",
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ func toVerificationResult(p *policy.Policy, input *policy.Input, result *policy.
|
|||||||
Policy: vsaPolicy,
|
Policy: vsaPolicy,
|
||||||
VerificationResult: outcomeStr,
|
VerificationResult: outcomeStr,
|
||||||
VerifiedLevels: result.Summary.SLSALevels,
|
VerifiedLevels: result.Summary.SLSALevels,
|
||||||
|
InputAttestations: result.Summary.Inputs,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ func TestVerifyAttestations(t *testing.T) {
|
|||||||
ex, err := os.ReadFile(ExampleAttestation)
|
ex, err := os.ReadFile(ExampleAttestation)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
env := new(attestation.Envelope)
|
env := new(attestation.EnvelopeReference)
|
||||||
err = json.Unmarshal(ex, env)
|
err = json.Unmarshal(ex, env)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
resolver := &attestation.MockResolver{
|
resolver := &attestation.MockResolver{
|
||||||
Envs: []*attestation.Envelope{env},
|
Envs: []*attestation.EnvelopeReference{env},
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@@ -124,7 +124,15 @@ func TestVSA(t *testing.T) {
|
|||||||
assert.Equal(t, PassPolicyDir+"/policy.rego", attestationPredicate.Policy.DownloadLocation)
|
assert.Equal(t, PassPolicyDir+"/policy.rego", attestationPredicate.Policy.DownloadLocation)
|
||||||
assert.Equal(t, "https://docker.com/official/policy/v0.1", attestationPredicate.Policy.URI)
|
assert.Equal(t, "https://docker.com/official/policy/v0.1", attestationPredicate.Policy.URI)
|
||||||
// this is the digest of the policy file
|
// this is the digest of the policy file
|
||||||
assert.Equal(t, map[string]string{"sha256": "ae71defe3b9ecebdf4f939a396b68884d0cba3c2c9d78ce5e64146d9487b0ade"}, attestationPredicate.Policy.Digest)
|
assert.Equal(t, map[string]string{"sha256": "fe1d4973f3521009a3adec206946e12aae935a2aceeb1e01f52b5d4cb9de79a5"}, attestationPredicate.Policy.Digest)
|
||||||
|
assert.Greater(t, len(attestationPredicate.InputAttestations), 0)
|
||||||
|
for _, input := range attestationPredicate.InputAttestations {
|
||||||
|
require.NotEmpty(t, input.Digest)
|
||||||
|
digest, ok := input.Digest["sha256"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.NotEmpty(t, digest)
|
||||||
|
assert.Contains(t, []string{"application/vnd.in-toto.provenance+dsse", "application/vnd.in-toto.spdx+dsse"}, input.MediaType)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVerificationFailure(t *testing.T) {
|
func TestVerificationFailure(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user