refactor: remove evelopeStyle

This commit is contained in:
mrjoelkamp
2024-04-30 09:34:17 -05:00
parent 90393ea6fd
commit 94d7f99c3c
3 changed files with 33 additions and 101 deletions

View File

@@ -15,7 +15,6 @@ import (
"github.com/google/go-containerregistry/pkg/v1/static"
"github.com/google/go-containerregistry/pkg/v1/types"
intoto "github.com/in-toto/in-toto-golang/in_toto"
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/secure-systems-lab/go-securesystemslib/dsse"
)
@@ -81,44 +80,17 @@ func SignIndexAttestations(ctx context.Context, idx v1.ImageIndex, signer dsse.S
}
ann[InTotoReferenceLifecycleStage] = LifecycleStageExperimental
var env *attestation.Envelope
var mediaType string
switch opts.EnvelopeStyle {
case OCIContentDescriptor:
// Ensure we sign just the digest, size, and media type
payloadDesc := v1.Descriptor{
Digest: layerDesc.Digest,
Size: layerDesc.Size,
MediaType: layerDesc.MediaType,
}
payload, err := json.Marshal(payloadDesc)
if err != nil {
return nil, fmt.Errorf("failed to marshal descriptor: %w", err)
}
env, err = attestation.SignDSSE(ctx, payload, ociv1.MediaTypeDescriptor, signer)
if err != nil {
return nil, fmt.Errorf("failed to sign statement: %w", err)
}
ann[oci.DockerReferenceDigest] = layerDesc.Digest.String()
// this is a reference type
opts.Replace = false
mediaType = attestation.OCIDescriptorDSSEMediaType
case EmbeddedDSSE:
payload, err := json.Marshal(stmt)
if err != nil {
return nil, fmt.Errorf("failed to marshal statement: %w", err)
}
env, err = attestation.SignDSSE(ctx, payload, intoto.PayloadType, signer)
if err != nil {
return nil, fmt.Errorf("failed to sign statement: %w", err)
}
mediaType, err = attestation.DSSEMediaType(stmt.PredicateType)
if err != nil {
return nil, fmt.Errorf("failed to get DSSE media type: %w", err)
}
default:
return nil, fmt.Errorf("unknown envelope style %q", opts.EnvelopeStyle)
payload, err := json.Marshal(stmt)
if err != nil {
return nil, fmt.Errorf("failed to marshal statement: %w", err)
}
env, err := attestation.SignDSSE(ctx, payload, intoto.PayloadType, signer)
if err != nil {
return nil, fmt.Errorf("failed to sign statement: %w", err)
}
mediaType, err := attestation.DSSEMediaType(stmt.PredicateType)
if err != nil {
return nil, fmt.Errorf("failed to get DSSE media type: %w", err)
}
data, err := json.Marshal(env)

View File

@@ -35,18 +35,14 @@ func TestSignVerifyOCILayout(t *testing.T) {
TestImage string
expectedStatements int
expectedAttestations int
envelopeStyle envelopeStyle
replace bool
}{
{"signed replaced (does nothing)", UnsignedTestImage, 4, 4, OCIContentDescriptor, true},
{"without replace", UnsignedTestImage, 4, 4, OCIContentDescriptor, false},
{"embedded", UnsignedTestImage, 0, 6, EmbeddedDSSE, true},
{"embedded", UnsignedTestImage, 4, 6, EmbeddedDSSE, false},
{"signed replaced (does nothing)", UnsignedTestImage, 0, 6, true},
{"without replace", UnsignedTestImage, 4, 6, false},
// image without provenance doesn't fail
{"no provenance (replace)", NoProvenanceImage, 0, 4, EmbeddedDSSE, true},
{"no provenance (no replace)", NoProvenanceImage, 2, 4, EmbeddedDSSE, false},
{"no provenance (replace)", NoProvenanceImage, 0, 4, true},
{"no provenance (no replace)", NoProvenanceImage, 2, 4, false},
}
policyResolver := &policy.PolicyOptions{
LocalPolicyDir: LocalPolicyDir,
@@ -56,8 +52,7 @@ func TestSignVerifyOCILayout(t *testing.T) {
tempDir := test.CreateTempDir(t, "", TestTempDir)
outputLayout := tempDir
opts := &SigningOptions{
Replace: tc.replace,
EnvelopeStyle: tc.envelopeStyle,
Replace: tc.replace,
VSAOptions: &attestation.VSAOptions{
BuildLevel: "SLSA_BUILD_LEVEL_3",
PolicyURI: "https://docker.com/attest/policy",
@@ -94,39 +89,22 @@ func TestSignVerifyOCILayout(t *testing.T) {
vsas, err := test.ExtractAnnotatedStatements(tempDir, mt)
assert.NoError(t, err)
assert.Equalf(t, len(vsas), 2, "expected %d vsa statement, got %d", 2, len(vsas))
var allEnvelopes []*test.AnnotatedStatement
for _, predicate := range []string{intoto.PredicateSPDX, v02.PredicateSLSAProvenance, attestation.VSAPredicateType} {
mt, _ := attestation.DSSEMediaType(predicate)
statements, err := test.ExtractAnnotatedStatements(tempDir, mt)
assert.NoError(t, err)
allEnvelopes = append(allEnvelopes, statements...)
switch tc.envelopeStyle {
case OCIContentDescriptor:
{
statements, err := test.ExtractAnnotatedStatements(tempDir, intoto.PayloadType)
assert.NoError(t, err)
assert.Equalf(t, tc.expectedStatements, len(statements), "expected %d statement, got %d", tc.expectedStatements, len(statements))
statements, err = test.ExtractAnnotatedStatements(tempDir, attestation.OCIDescriptorDSSEMediaType)
assert.NoError(t, err)
assert.Equalf(t, tc.expectedAttestations, len(statements), "expected %d attestations, got %d", tc.expectedAttestations, len(statements))
}
case EmbeddedDSSE:
{
var allEnvelopes []*test.AnnotatedStatement
for _, predicate := range []string{intoto.PredicateSPDX, v02.PredicateSLSAProvenance, attestation.VSAPredicateType} {
mt, _ := attestation.DSSEMediaType(predicate)
statements, err := test.ExtractAnnotatedStatements(tempDir, mt)
assert.NoError(t, err)
allEnvelopes = append(allEnvelopes, statements...)
for _, stmt := range statements {
assert.Equalf(t, predicate, stmt.Annotations[oci.InTotoPredicateType], "expected predicate-type annotation to be set to %s, got %s", predicate, stmt.Annotations[oci.InTotoPredicateType])
assert.Equalf(t, LifecycleStageExperimental, stmt.Annotations[InTotoReferenceLifecycleStage], "expected reference lifecycle stage annotation to be set to %s, got %s", LifecycleStageExperimental, stmt.Annotations[InTotoReferenceLifecycleStage])
}
}
assert.Equalf(t, tc.expectedAttestations, len(allEnvelopes), "expected %d attestations, got %d", tc.expectedAttestations, len(allEnvelopes))
statements, err := test.ExtractAnnotatedStatements(tempDir, intoto.PayloadType)
assert.NoError(t, err)
assert.Equalf(t, tc.expectedStatements, len(statements), "expected %d statement, got %d", tc.expectedStatements, len(statements))
for _, stmt := range statements {
assert.Equalf(t, predicate, stmt.Annotations[oci.InTotoPredicateType], "expected predicate-type annotation to be set to %s, got %s", predicate, stmt.Annotations[oci.InTotoPredicateType])
assert.Equalf(t, LifecycleStageExperimental, stmt.Annotations[InTotoReferenceLifecycleStage], "expected reference lifecycle stage annotation to be set to %s, got %s", LifecycleStageExperimental, stmt.Annotations[InTotoReferenceLifecycleStage])
}
}
assert.Equalf(t, tc.expectedAttestations, len(allEnvelopes), "expected %d attestations, got %d", tc.expectedAttestations, len(allEnvelopes))
statements, err := test.ExtractAnnotatedStatements(tempDir, intoto.PayloadType)
assert.NoError(t, err)
assert.Equalf(t, tc.expectedStatements, len(statements), "expected %d statement, got %d", tc.expectedStatements, len(statements))
})
}
}

View File

@@ -1,33 +1,15 @@
package attest
import (
"fmt"
"github.com/docker/attest/pkg/attestation"
)
type envelopeStyle string
const (
OCIContentDescriptor envelopeStyle = "oci-content-descriptor"
EmbeddedDSSE envelopeStyle = "embedded-dsse"
InTotoReferenceLifecycleStage = "vnd.docker.lifecycle-stage"
LifecycleStageExperimental = "experimental"
InTotoReferenceLifecycleStage = "vnd.docker.lifecycle-stage"
LifecycleStageExperimental = "experimental"
)
type SigningOptions struct {
Replace bool
EnvelopeStyle envelopeStyle
VSAOptions *attestation.VSAOptions
}
func EnvelopeStyle(style string) (envelopeStyle, error) {
switch style {
case string(OCIContentDescriptor):
return OCIContentDescriptor, nil
case string(EmbeddedDSSE):
return EmbeddedDSSE, nil
default:
return "", fmt.Errorf("unknown envelope style %q", style)
}
Replace bool
VSAOptions *attestation.VSAOptions
}