Skip to content

Commit c5545ed

Browse files
steizahaydentherapper
authored andcommitted
Partially populate the output of cosign verify when working with new bundles (#4416)
* Implement container image context in verify command * Use conformance on main for now (waiting for new release) --------- Signed-off-by: Zach Steindler <[email protected]>
1 parent e191024 commit c5545ed

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

.github/workflows/conformance.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ jobs:
4444

4545
- run: make cosign conformance
4646

47-
- uses: sigstore/sigstore-conformance@1d8b0cdd88fa7fb5a8510e51faf6ccad8c96f10a # v0.0.20
47+
- uses: sigstore/sigstore-conformance@main
4848
with:
4949
entrypoint: ${{ github.workspace }}/conformance

cmd/cosign/cli/verify/verify.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"path/filepath"
3030

3131
"github.com/google/go-containerregistry/pkg/name"
32+
"github.com/in-toto/in-toto-golang/in_toto"
3233
"github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio"
3334
"github.com/sigstore/cosign/v2/cmd/cosign/cli/options"
3435
"github.com/sigstore/cosign/v2/cmd/cosign/cli/rekor"
@@ -41,7 +42,9 @@ import (
4142
"github.com/sigstore/cosign/v2/pkg/cosign/pivkey"
4243
"github.com/sigstore/cosign/v2/pkg/cosign/pkcs11key"
4344
"github.com/sigstore/cosign/v2/pkg/oci"
45+
"github.com/sigstore/cosign/v2/pkg/oci/static"
4446
sigs "github.com/sigstore/cosign/v2/pkg/signature"
47+
"github.com/sigstore/protobuf-specs/gen/pb-go/dsse"
4548
"github.com/sigstore/sigstore-go/pkg/root"
4649
"github.com/sigstore/sigstore/pkg/cryptoutils"
4750
"github.com/sigstore/sigstore/pkg/signature"
@@ -344,6 +347,11 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
344347
if err != nil {
345348
return err
346349
}
350+
351+
verifiedOutput, err := transformOutput(verified, ref.Name())
352+
if err == nil {
353+
verified = verifiedOutput
354+
}
347355
} else {
348356
ref, err = sign.GetAttachedImageRef(ref, c.Attachment, ociremoteOpts...)
349357
if err != nil {
@@ -633,3 +641,56 @@ func loadCertsKeylessVerification(certChainFile string,
633641

634642
return nil
635643
}
644+
645+
func transformOutput(verified []oci.Signature, name string) (verifiedOutput []oci.Signature, err error) {
646+
for _, v := range verified {
647+
dssePayload, err := v.Payload()
648+
if err != nil {
649+
return nil, err
650+
}
651+
var dsseEnvelope dsse.Envelope
652+
err = json.Unmarshal(dssePayload, &dsseEnvelope)
653+
if err != nil {
654+
return nil, err
655+
}
656+
if dsseEnvelope.PayloadType != in_toto.PayloadType {
657+
return nil, fmt.Errorf("unable to understand payload type %s", dsseEnvelope.PayloadType)
658+
}
659+
var intotoStatement in_toto.StatementHeader
660+
err = json.Unmarshal(dsseEnvelope.Payload, &intotoStatement)
661+
if err != nil {
662+
return nil, err
663+
}
664+
if len(intotoStatement.Subject) < 1 || len(intotoStatement.Subject[0].Digest) < 1 {
665+
return nil, fmt.Errorf("no intoto subject or digest found")
666+
}
667+
668+
var digest string
669+
for k, v := range intotoStatement.Subject[0].Digest {
670+
digest = k + ":" + v
671+
}
672+
673+
sci := payload.SimpleContainerImage{
674+
Critical: payload.Critical{
675+
Identity: payload.Identity{
676+
DockerReference: name,
677+
},
678+
Image: payload.Image{
679+
DockerManifestDigest: digest,
680+
},
681+
Type: intotoStatement.PredicateType,
682+
},
683+
}
684+
p, err := json.Marshal(sci)
685+
if err != nil {
686+
return nil, err
687+
}
688+
att, err := static.NewAttestation(p)
689+
if err != nil {
690+
return nil, err
691+
}
692+
verifiedOutput = append(verifiedOutput, att)
693+
}
694+
695+
return verifiedOutput, nil
696+
}

cmd/cosign/cli/verify/verify_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,52 @@ func TestLoadCertsKeylessVerification(t *testing.T) {
346346
})
347347
}
348348
}
349+
func TestTransformOutputSuccess(t *testing.T) {
350+
// Build minimal in-toto statement
351+
stmt := `{
352+
"_type": "https://in-toto.io/Statement/v0.1",
353+
"subject": [
354+
{ "name": "artifact", "digest": { "sha256": "deadbeef" } }
355+
],
356+
"predicateType": "https://slsa.dev/provenance/v0.2"
357+
}`
358+
// DSSE payloadType for in-toto
359+
payloadType := "application/vnd.in-toto+json"
360+
encodedStmt := base64.StdEncoding.EncodeToString([]byte(stmt))
361+
dsseEnv := fmt.Sprintf(`{
362+
"payloadType": "%s",
363+
"payload": "%s",
364+
"signatures": [
365+
{ "keyid": "test", "sig": "MAo=" }
366+
]
367+
}`, payloadType, encodedStmt)
368+
369+
sig, err := static.NewSignature([]byte(dsseEnv), "")
370+
if err != nil {
371+
t.Fatalf("creating static signature: %v", err)
372+
}
373+
fmt.Println(dsseEnv)
374+
375+
name := "example.com/my/image"
376+
out, err := transformOutput([]oci.Signature{sig}, name)
377+
if err != nil {
378+
t.Fatalf("transformOutput returned error: %v", err)
379+
}
380+
if len(out) != 1 {
381+
t.Fatalf("expected 1 transformed signature, got %d", len(out))
382+
}
383+
384+
payloadBytes, err := out[0].Payload()
385+
if err != nil {
386+
t.Fatalf("reading transformed payload: %v", err)
387+
}
388+
389+
var sci payload.SimpleContainerImage
390+
if err := json.Unmarshal(payloadBytes, &sci); err != nil {
391+
t.Fatalf("unmarshal transformed payload: %v", err)
392+
}
393+
394+
assert.Equal(t, name, sci.Critical.Identity.DockerReference, "docker reference mismatch")
395+
assert.Equal(t, "sha256:deadbeef", sci.Critical.Image.DockerManifestDigest, "digest mismatch")
396+
assert.Equal(t, "https://slsa.dev/provenance/v0.2", sci.Critical.Type, "type mismatch")
397+
}

0 commit comments

Comments
 (0)