Skip to content

Commit

Permalink
Avoid remote.Gets when the ref contains a digest (#487)
Browse files Browse the repository at this point in the history
* Avoid remote.Gets when the ref contains a digest

Signed-off-by: Jason Hall <[email protected]>

* license header

Signed-off-by: Jason Hall <[email protected]>

* appease lint

Signed-off-by: Jason Hall <[email protected]>
  • Loading branch information
imjasonh authored Jul 27, 2021
1 parent ade62cd commit 1a660a2
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 68 deletions.
11 changes: 5 additions & 6 deletions cmd/cosign/cli/attach/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"os"

"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/types"
"github.com/peterbourgon/ff/v3/ffcli"

Expand Down Expand Up @@ -69,21 +68,21 @@ func SBOMCmd(ctx context.Context, sbomRef, sbomType, imageRef string) error {
return err
}

b, err := ioutil.ReadFile(sbomRef)
h, err := cli.Digest(ctx, ref)
if err != nil {
return err
}

regClientOpts := cli.DefaultRegistryClientOpts(ctx)
get, err := remote.Get(ref, regClientOpts...)
b, err := ioutil.ReadFile(sbomRef)
if err != nil {
return err
}

repo := ref.Context()
dstRef := cosign.AttachedImageTag(repo, get, cosign.SBOMTagSuffix)
dstRef := cosign.AttachedImageTag(repo, h, cosign.SBOMTagSuffix)

fmt.Fprintf(os.Stderr, "Uploading SBOM file for [%s] to [%s] with mediaType [%s].\n", ref.Name(), dstRef.Name(), sbomType)
if _, err := cremote.UploadFile(b, dstRef, types.MediaType(sbomType), types.OCIConfigJSON, regClientOpts...); err != nil {
if _, err := cremote.UploadFile(b, dstRef, types.MediaType(sbomType), types.OCIConfigJSON, cli.DefaultRegistryClientOpts(ctx)...); err != nil {
return err
}

Expand Down
13 changes: 5 additions & 8 deletions cmd/cosign/cli/attach/sig.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"path/filepath"

"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/peterbourgon/ff/v3/ffcli"

"github.com/sigstore/cosign/cmd/cosign/cli"
Expand Down Expand Up @@ -56,8 +55,6 @@ func Signature() *ffcli.Command {
}

func SignatureCmd(ctx context.Context, sigRef, payloadRef, imageRef string) error {
var b64SigBytes []byte

b64SigBytes, err := signatureBytes(sigRef)
if err != nil {
return err
Expand All @@ -70,22 +67,21 @@ func SignatureCmd(ctx context.Context, sigRef, payloadRef, imageRef string) erro
return err
}

regClientOpts := cli.DefaultRegistryClientOpts(ctx)
get, err := remote.Get(ref, regClientOpts...)
h, err := cli.Digest(ctx, ref)
if err != nil {
return err
}
repo := ref.Context()
img := repo.Digest(get.Digest.String())

sigRepo, err := cli.TargetRepositoryForImage(ref)
if err != nil {
return err
}
dstRef := cosign.AttachedImageTag(sigRepo, get, cosign.SignatureTagSuffix)
dstRef := cosign.AttachedImageTag(sigRepo, h, cosign.SignatureTagSuffix)

var payload []byte
if payloadRef == "" {
repo := ref.Context()
img := repo.Digest(h.String())
payload, err = (&sigPayload.Cosign{Image: img}).MarshalJSON()
} else {
payload, err = ioutil.ReadFile(filepath.Clean(payloadRef))
Expand All @@ -99,6 +95,7 @@ func SignatureCmd(ctx context.Context, sigRef, payloadRef, imageRef string) erro
if err != nil {
return err
}
regClientOpts := cli.DefaultRegistryClientOpts(ctx)
if _, err := cremote.UploadSignature(sigBytes, payload, dstRef, cremote.UploadOpts{RemoteOpts: regClientOpts}); err != nil {
return err
}
Expand Down
16 changes: 5 additions & 11 deletions cmd/cosign/cli/attest.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (

"github.com/google/go-containerregistry/pkg/name"
ggcrV1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/in-toto/in-toto-golang/in_toto"
"github.com/peterbourgon/ff/v3/ffcli"
"github.com/pkg/errors"
Expand Down Expand Up @@ -127,13 +126,12 @@ func AttestCmd(ctx context.Context, ko KeyOpts, imageRef string, certPath string
if err != nil {
return errors.Wrap(err, "parsing reference")
}
get, err := remote.Get(ref, remoteOpts...)
h, err := Digest(ctx, ref)
if err != nil {
return errors.Wrap(err, "getting remote image")
return err
}

repo := ref.Context()
img := repo.Digest(get.Digest.String())
img := repo.Digest(h.String())

sv, err := signerFromKeyOpts(ctx, certPath, ko)
if err != nil {
Expand All @@ -155,7 +153,7 @@ func AttestCmd(ctx context.Context, ko KeyOpts, imageRef string, certPath string
{
Name: repo.String(),
Digest: map[string]string{
"sha256": get.Digest.Hex,
"sha256": h.Hex,
},
},
},
Expand Down Expand Up @@ -187,11 +185,7 @@ func AttestCmd(ctx context.Context, ko KeyOpts, imageRef string, certPath string
if err != nil {
return err
}
attRef := cosign.AttachedImageTag(sigRepo, &remote.Descriptor{
Descriptor: ggcrV1.Descriptor{
Digest: imgHash,
},
}, cosign.AttestationTagSuffix)
attRef := cosign.AttachedImageTag(sigRepo, imgHash, cosign.AttestationTagSuffix)

uo := cremote.UploadOpts{
Cert: sv.Cert,
Expand Down
9 changes: 3 additions & 6 deletions cmd/cosign/cli/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"flag"
"fmt"

"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/peterbourgon/ff/v3/ffcli"
Expand Down Expand Up @@ -53,9 +52,7 @@ func CleanCmd(ctx context.Context, imageRef string) error {
return err
}

remoteOpts := []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain), remote.WithContext(ctx)}
// TODO: just return the descriptor directly if we have a digest reference.
desc, err := remote.Get(ref, remoteOpts...)
h, err := Digest(ctx, ref)
if err != nil {
return err
}
Expand All @@ -64,12 +61,12 @@ func CleanCmd(ctx context.Context, imageRef string) error {
if err != nil {
return err
}
sigRef := cosign.AttachedImageTag(sigRepo, desc, cosign.SignatureTagSuffix)
sigRef := cosign.AttachedImageTag(sigRepo, h, cosign.SignatureTagSuffix)
fmt.Println(sigRef)

fmt.Println("Deleting signature metadata...")

err = remote.Delete(sigRef, remoteOpts...)
err = remote.Delete(sigRef, DefaultRegistryClientOpts(ctx)...)
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/cosign/cli/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ func CopyCmd(ctx context.Context, srcImg, dstImg string, sigOnly, force bool) er
if err != nil {
return err
}
regClientOpts := DefaultRegistryClientOpts(ctx)
gotSrc, err := remote.Get(srcRef, regClientOpts...)

h, err := Digest(ctx, srcRef)
if err != nil {
return err
}
Expand All @@ -78,11 +78,12 @@ func CopyCmd(ctx context.Context, srcImg, dstImg string, sigOnly, force bool) er
return err
}

sigSrcRef := cosign.AttachedImageTag(srcSigRepo, gotSrc, cosign.SignatureTagSuffix)
sigSrcRef := cosign.AttachedImageTag(srcSigRepo, h, cosign.SignatureTagSuffix)

dstRepoRef := dstRef.Context()
sigDstRef := dstRepoRef.Tag(sigSrcRef.Identifier())

regClientOpts := DefaultRegistryClientOpts(ctx)
if err := copyImage(sigSrcRef, sigDstRef, force, regClientOpts...); err != nil {
return err
}
Expand Down
38 changes: 38 additions & 0 deletions cmd/cosign/cli/digest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2021 The Sigstore Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cli

import (
"context"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
)

// Digest returns the digest of the image at the reference.
//
// If the reference is by digest already, it simply extracts the digest.
// Otherwise, it looks up the digest from the registry.
func Digest(ctx context.Context, ref name.Reference) (v1.Hash, error) {
if d, ok := ref.(name.Digest); ok {
return v1.NewHash(d.DigestStr())
}
desc, err := remote.Get(ref, DefaultRegistryClientOpts(ctx)...)
if err != nil {
return v1.Hash{}, err
}
return desc.Digest, nil
}
7 changes: 2 additions & 5 deletions cmd/cosign/cli/download/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"io/ioutil"
"os"

"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/peterbourgon/ff/v3/ffcli"
Expand Down Expand Up @@ -56,15 +55,13 @@ func SBOMCmd(ctx context.Context, imageRef string, out io.Writer) ([]string, err
return nil, err
}

auth := remote.WithAuthFromKeychain(authn.DefaultKeychain)

get, err := remote.Get(ref, auth)
h, err := cli.Digest(ctx, ref)
if err != nil {
return nil, err
}

repo := ref.Context()
dstRef := cosign.AttachedImageTag(repo, get, cosign.SBOMTagSuffix)
dstRef := cosign.AttachedImageTag(repo, h, cosign.SBOMTagSuffix)
img, err := remote.Image(dstRef, cli.DefaultRegistryClientOpts(ctx)...)
if err != nil {
return nil, err
Expand Down
6 changes: 1 addition & 5 deletions cmd/cosign/cli/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,7 @@ func SignCmd(ctx context.Context, ko KeyOpts, annotations map[string]interface{}
if err != nil {
return err
}
sigRef := cosign.AttachedImageTag(sigRepo, &remote.Descriptor{
Descriptor: ggcrV1.Descriptor{
Digest: imgHash,
},
}, cosign.SignatureTagSuffix)
sigRef := cosign.AttachedImageTag(sigRepo, imgHash, cosign.SignatureTagSuffix)

uo := cremote.UploadOpts{
Cert: sv.Cert,
Expand Down
7 changes: 2 additions & 5 deletions cmd/cosign/cli/triangulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ import (
"flag"
"fmt"

"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/peterbourgon/ff/v3/ffcli"

"github.com/sigstore/cosign/pkg/cosign"
Expand Down Expand Up @@ -52,8 +50,7 @@ func MungeCmd(ctx context.Context, imageRef string) error {
return err
}

// TODO: just return the descriptor directly if we have a digest reference.
desc, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain), remote.WithContext(ctx))
h, err := Digest(ctx, ref)
if err != nil {
return err
}
Expand All @@ -62,7 +59,7 @@ func MungeCmd(ctx context.Context, imageRef string) error {
if err != nil {
return err
}
dstRef := cosign.AttachedImageTag(sigRepo, desc, cosign.SignatureTagSuffix)
dstRef := cosign.AttachedImageTag(sigRepo, h, cosign.SignatureTagSuffix)

fmt.Println(dstRef.Name())
return nil
Expand Down
11 changes: 6 additions & 5 deletions pkg/cosign/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"

"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/pkg/errors"
cremote "github.com/sigstore/cosign/pkg/cosign/remote"
Expand Down Expand Up @@ -56,9 +57,9 @@ const (
AttestationTagSuffix = ".att"
)

func AttachedImageTag(repo name.Repository, imgDesc *remote.Descriptor, tagSuffix string) name.Tag {
func AttachedImageTag(repo name.Repository, digest v1.Hash, tagSuffix string) name.Tag {
// sha256:d34db33f -> sha256-d34db33f.suffix
tagStr := strings.ReplaceAll(imgDesc.Digest.String(), ":", "-") + tagSuffix
tagStr := strings.ReplaceAll(digest.String(), ":", "-") + tagSuffix
return repo.Tag(tagStr)
}

Expand All @@ -67,11 +68,11 @@ func FetchSignaturesForImage(ctx context.Context, signedImgRef name.Reference, s
if err != nil {
return nil, err
}
return FetchSignaturesForDescriptor(ctx, signedImgDesc, sigRepo, sigTagSuffix, registryOpts...)
return FetchSignaturesForImageDigest(ctx, signedImgDesc.Descriptor.Digest, sigRepo, sigTagSuffix, registryOpts...)
}

func FetchSignaturesForDescriptor(ctx context.Context, signedDescriptor *remote.Descriptor, sigRepo name.Repository, sigTagSuffix string, registryOpts ...remote.Option) ([]SignedPayload, error) {
sigImgDesc, err := remote.Get(AttachedImageTag(sigRepo, signedDescriptor, sigTagSuffix), registryOpts...)
func FetchSignaturesForImageDigest(ctx context.Context, signedImageDigest v1.Hash, sigRepo name.Repository, sigTagSuffix string, registryOpts ...remote.Option) ([]SignedPayload, error) {
sigImgDesc, err := remote.Get(AttachedImageTag(sigRepo, signedImageDigest, sigTagSuffix), registryOpts...)
if err != nil {
return nil, errors.Wrap(err, "getting signature manifest")
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/cosign/verifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ import (
"github.com/sigstore/sigstore/pkg/signature/payload"
)

func SimpleClaimVerifier(sp SignedPayload, desc *v1.Descriptor, annotations map[string]interface{}) error {
func SimpleClaimVerifier(sp SignedPayload, digest v1.Hash, annotations map[string]interface{}) error {
ss := &payload.SimpleContainerImage{}
if err := json.Unmarshal(sp.Payload, ss); err != nil {
return err
}

if err := sp.VerifyClaims(desc, ss); err != nil {
if err := sp.VerifyClaims(digest, ss); err != nil {
return err
}

Expand All @@ -42,7 +42,7 @@ func SimpleClaimVerifier(sp SignedPayload, desc *v1.Descriptor, annotations map[
return nil
}

func IntotoSubjectClaimVerifier(sp SignedPayload, desc *v1.Descriptor, _ map[string]interface{}) error {
func IntotoSubjectClaimVerifier(sp SignedPayload, digest v1.Hash, _ map[string]interface{}) error {
st := &in_toto.Statement{}
if err := json.Unmarshal(sp.Payload, st); err != nil {
return err
Expand All @@ -54,7 +54,7 @@ func IntotoSubjectClaimVerifier(sp SignedPayload, desc *v1.Descriptor, _ map[str
continue
}
subjDigest := "sha256:" + dgst
if subjDigest == desc.Digest.String() {
if subjDigest == digest.String() {
return nil
}
}
Expand Down
Loading

0 comments on commit 1a660a2

Please sign in to comment.