Skip to content

Commit

Permalink
Store attestations in the layer (payload) rather than the annotation. (
Browse files Browse the repository at this point in the history
…#579)

These can be quite large, especially when they are SBOMs.

Signed-off-by: Dan Lorenc <dlorenc@google.com>
  • Loading branch information
dlorenc committed Aug 26, 2021
1 parent a657741 commit cf9cced
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
4 changes: 3 additions & 1 deletion cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,9 @@ func AttestCmd(ctx context.Context, ko KeyOpts, imageRef string, certPath string
}

fmt.Fprintln(os.Stderr, "Pushing attestation to:", attRef.String())
if _, err = cremote.UploadSignature(sig, payload, attRef, uo); err != nil {
// An attestation represents both the signature and payload. So store the entire thing
// in the payload field since they can get large
if _, err = cremote.UploadSignature([]byte{}, sig, attRef, uo); err != nil {
return errors.Wrap(err, "uploading")
}

Expand Down
17 changes: 16 additions & 1 deletion cmd/cosign/cli/verify_attestation.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package cli
import (
"context"
"flag"
"io"

"github.com/google/go-containerregistry/pkg/name"
"github.com/peterbourgon/ff/v3/ffcli"
Expand Down Expand Up @@ -93,6 +94,17 @@ EXAMPLES
}
}

// DSSE messages contain the signature and payload in one object, but our interface expects a signature and payload
// This means we need to use one field and ignore the other. The DSSE verifier upstream uses the signature field and ignores
// The message field, but we want the reverse here.
type reverseDSSEVerifier struct {
signature.Verifier
}

func (w *reverseDSSEVerifier) VerifySignature(s io.Reader, m io.Reader, opts ...signature.VerifyOption) error {
return w.Verifier.VerifySignature(m, nil, opts...)
}

// Exec runs the verification command
func (c *VerifyAttestationCommand) Exec(ctx context.Context, args []string) (err error) {
if len(args) == 0 {
Expand Down Expand Up @@ -134,7 +146,10 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, args []string) (err
return errors.Wrap(err, "initializing piv token verifier")
}
}
co.SigVerifier = dsse.WrapVerifier(pubKey)

co.SigVerifier = &reverseDSSEVerifier{
Verifier: dsse.WrapVerifier(pubKey),
}

for _, imageRef := range args {
ref, err := name.ParseReference(imageRef)
Expand Down
15 changes: 13 additions & 2 deletions pkg/cosign/verifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package cosign

import (
"encoding/base64"
"encoding/json"

v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/in-toto/in-toto-golang/in_toto"
"github.com/in-toto/in-toto-golang/pkg/ssl"
"github.com/pkg/errors"
"github.com/sigstore/sigstore/pkg/signature/payload"
)
Expand All @@ -45,11 +47,20 @@ func SimpleClaimVerifier(sp SignedPayload, imageDigest v1.Hash, annotations map[

// IntotoSubjectClaimVerifier verifies that SignedPayload.Payload is an Intoto statement which references the given image digest.
func IntotoSubjectClaimVerifier(sp SignedPayload, imageDigest v1.Hash, _ map[string]interface{}) error {
st := &in_toto.Statement{}
if err := json.Unmarshal(sp.Payload, st); err != nil {
// The payload here is an envelope. We already verified the signature earlier.
e := ssl.Envelope{}
if err := json.Unmarshal(sp.Payload, &e); err != nil {
return err
}
stBytes, err := base64.StdEncoding.DecodeString(e.Payload)
if err != nil {
return err
}

st := in_toto.Statement{}
if err := json.Unmarshal(stBytes, &st); err != nil {
return err
}
for _, subj := range st.StatementHeader.Subject {
dgst, ok := subj.Digest["sha256"]
if !ok {
Expand Down

0 comments on commit cf9cced

Please sign in to comment.