diff --git a/copy/copy.go b/copy/copy.go index c7500e96f..6758d4de1 100644 --- a/copy/copy.go +++ b/copy/copy.go @@ -19,7 +19,6 @@ import ( "github.com/containers/image/v5/internal/imagesource" "github.com/containers/image/v5/internal/pkg/platform" "github.com/containers/image/v5/internal/private" - internalsig "github.com/containers/image/v5/internal/signature" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/pkg/blobinfocache" "github.com/containers/image/v5/pkg/compression" @@ -405,23 +404,11 @@ func (c *copier) copyMultipleImages(ctx context.Context, policyContext *signatur } updatedList := originalList.Clone() - // Read and/or clear the set of signatures for this list. - var sigs []internalsig.Signature - if options.RemoveSignatures { - sigs = []internalsig.Signature{} - } else { - c.Printf("Getting image list signatures\n") - s, err := unparsedToplevel.UntrustedSignatures(ctx) - if err != nil { - return nil, fmt.Errorf("reading signatures: %w", err) - } - sigs = s - } - if len(sigs) != 0 { - c.Printf("Checking if image list destination supports signatures\n") - if err := c.dest.SupportsSignatures(ctx); err != nil { - return nil, fmt.Errorf("Can not copy signatures to %s: %w", transports.ImageName(c.dest.Reference()), err) - } + sigs, err := c.sourceSignatures(ctx, unparsedToplevel, options, + "Getting image list signatures", + "Checking if image list destination supports signatures") + if err != nil { + return nil, err } // If the destination is a digested reference, make a note of that, determine what digest value we're @@ -656,22 +643,11 @@ func (c *copier) copyOneImage(ctx context.Context, policyContext *signature.Poli return nil, "", "", err } - var sigs []internalsig.Signature - if options.RemoveSignatures { - sigs = []internalsig.Signature{} - } else { - c.Printf("Getting image source signatures\n") - s, err := src.UntrustedSignatures(ctx) - if err != nil { - return nil, "", "", fmt.Errorf("reading signatures: %w", err) - } - sigs = s - } - if len(sigs) != 0 { - c.Printf("Checking if image destination supports signatures\n") - if err := c.dest.SupportsSignatures(ctx); err != nil { - return nil, "", "", fmt.Errorf("Can not copy signatures to %s: %w", transports.ImageName(c.dest.Reference()), err) - } + sigs, err := c.sourceSignatures(ctx, src, options, + "Getting image source signatures", + "Checking if image destination supports signatures") + if err != nil { + return nil, "", "", err } // Determine if we're allowed to modify the manifest. diff --git a/copy/sign.go b/copy/sign.go index 0ea06f4bb..6c3d9d62c 100644 --- a/copy/sign.go +++ b/copy/sign.go @@ -1,15 +1,42 @@ package copy import ( + "context" "fmt" "github.com/containers/image/v5/docker/reference" + "github.com/containers/image/v5/internal/private" internalsig "github.com/containers/image/v5/internal/signature" "github.com/containers/image/v5/signature" "github.com/containers/image/v5/signature/sigstore" "github.com/containers/image/v5/transports" ) +// sourceSignatures returns signatures from unparsedSource based on options, +// and verifies that they can be used (to avoid copying a large image when we +// can tell in advance that it would ultimately fail) +func (c *copier) sourceSignatures(ctx context.Context, unparsed private.UnparsedImage, options *Options, + gettingSignaturesMessage, checkingDestMessage string) ([]internalsig.Signature, error) { + var sigs []internalsig.Signature + if options.RemoveSignatures { + sigs = []internalsig.Signature{} + } else { + c.Printf("%s\n", gettingSignaturesMessage) + s, err := unparsed.UntrustedSignatures(ctx) + if err != nil { + return nil, fmt.Errorf("reading signatures: %w", err) + } + sigs = s + } + if len(sigs) != 0 { + c.Printf("%s\n", checkingDestMessage) + if err := c.dest.SupportsSignatures(ctx); err != nil { + return nil, fmt.Errorf("Can not copy signatures to %s: %w", transports.ImageName(c.dest.Reference()), err) + } + } + return sigs, nil +} + // createSignature creates a new signature of manifest using keyIdentity. func (c *copier) createSignature(manifest []byte, keyIdentity string, passphrase string, identity reference.Named) (internalsig.Signature, error) { mech, err := signature.NewGPGSigningMechanism()