-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #108 from dtrudg/cosign-sourcesink-support
feat: support cosign signatures in OCI-SIF files
- Loading branch information
Showing
96 changed files
with
2,017 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,74 @@ | ||
module github.com/sylabs/oci-tools | ||
|
||
go 1.22.0 | ||
go 1.22.7 | ||
|
||
require ( | ||
github.com/containerd/platforms v0.2.1 | ||
github.com/google/go-containerregistry v0.20.2 | ||
github.com/opencontainers/image-spec v1.1.0 | ||
github.com/sebdah/goldie/v2 v2.5.5 | ||
github.com/sigstore/cosign/v2 v2.4.1 | ||
github.com/sylabs/sif/v2 v2.20.2 | ||
) | ||
|
||
require ( | ||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect | ||
github.com/blang/semver v3.5.1+incompatible // indirect | ||
github.com/containerd/log v0.1.0 // indirect | ||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect | ||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect | ||
github.com/docker/cli v27.1.1+incompatible // indirect | ||
github.com/docker/distribution v2.8.2+incompatible // indirect | ||
github.com/docker/docker-credential-helpers v0.7.0 // indirect | ||
github.com/google/go-cmp v0.5.9 // indirect | ||
github.com/docker/distribution v2.8.3+incompatible // indirect | ||
github.com/docker/docker-credential-helpers v0.8.0 // indirect | ||
github.com/dustin/go-humanize v1.0.1 // indirect | ||
github.com/go-chi/chi v4.1.2+incompatible // indirect | ||
github.com/go-jose/go-jose/v4 v4.0.4 // indirect | ||
github.com/go-openapi/analysis v0.23.0 // indirect | ||
github.com/go-openapi/errors v0.22.0 // indirect | ||
github.com/go-openapi/jsonpointer v0.21.0 // indirect | ||
github.com/go-openapi/jsonreference v0.21.0 // indirect | ||
github.com/go-openapi/loads v0.22.0 // indirect | ||
github.com/go-openapi/runtime v0.28.0 // indirect | ||
github.com/go-openapi/spec v0.21.0 // indirect | ||
github.com/go-openapi/strfmt v0.23.0 // indirect | ||
github.com/go-openapi/swag v0.23.0 // indirect | ||
github.com/go-openapi/validate v0.24.0 // indirect | ||
github.com/google/go-cmp v0.6.0 // indirect | ||
github.com/google/uuid v1.6.0 // indirect | ||
github.com/klauspost/compress v1.16.5 // indirect | ||
github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect | ||
github.com/josharian/intern v1.0.0 // indirect | ||
github.com/klauspost/compress v1.17.9 // indirect | ||
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect | ||
github.com/mailru/easyjson v0.7.7 // indirect | ||
github.com/mitchellh/go-homedir v1.1.0 // indirect | ||
github.com/mitchellh/mapstructure v1.5.0 // indirect | ||
github.com/oklog/ulid v1.3.1 // indirect | ||
github.com/opencontainers/go-digest v1.0.0 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect | ||
github.com/sassoftware/relic v7.2.1+incompatible // indirect | ||
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect | ||
github.com/sergi/go-diff v1.2.0 // indirect | ||
github.com/sigstore/protobuf-specs v0.3.2 // indirect | ||
github.com/sigstore/rekor v1.3.6 // indirect | ||
github.com/sigstore/sigstore v1.8.11 // indirect | ||
github.com/sirupsen/logrus v1.9.3 // indirect | ||
github.com/vbatts/tar-split v0.11.3 // indirect | ||
golang.org/x/sync v0.2.0 // indirect | ||
github.com/spf13/cobra v1.8.1 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
github.com/theupdateframework/go-tuf v0.7.0 // indirect | ||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect | ||
github.com/vbatts/tar-split v0.11.5 // indirect | ||
go.mongodb.org/mongo-driver v1.14.0 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
go.uber.org/zap v1.27.0 // indirect | ||
golang.org/x/crypto v0.31.0 // indirect | ||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect | ||
golang.org/x/mod v0.20.0 // indirect | ||
golang.org/x/sync v0.8.0 // indirect | ||
golang.org/x/sys v0.28.0 // indirect | ||
golang.org/x/term v0.27.0 // indirect | ||
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect | ||
google.golang.org/protobuf v1.34.2 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2024-2025 Sylabs Inc. All rights reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package sourcesink | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/google/go-containerregistry/pkg/name" | ||
v1 "github.com/google/go-containerregistry/pkg/v1" | ||
cosignoci "github.com/sigstore/cosign/v2/pkg/oci" | ||
cosignremote "github.com/sigstore/cosign/v2/pkg/oci/remote" | ||
) | ||
|
||
// SignedDescriptor provides access to cosign signatures stored against it. | ||
type SignedDescriptor interface { | ||
// CosignImages checks for image manifests providing cosign signatures & | ||
// attestations that are associated with the image or index with the descriptor | ||
// If image manifests providing cosign signatures and / or attestations | ||
// exist, then these images are returned in a name.Reference -> v1.Image map. | ||
// | ||
// If recursive is true, then if the descriptor is an index, we also check for | ||
// signatures and attestations for each of its associated manifests. | ||
// | ||
// In the returned map, the images are referenced as '_cosign:<tag>', where | ||
// <tag> matches the tag at src. The '_cosign' repository placeholder string | ||
// is used instead of any original registry & repository names. | ||
CosignImages(ctx context.Context, recursive bool) ([]ReferencedImage, error) | ||
// SignedImage wraps an image Descriptor as a cosign oci.SignedImage, | ||
// allowing access to signatures and attestations stored alongside the image. | ||
SignedImage(context.Context) (cosignoci.SignedImage, error) | ||
// SignedImageIndex wraps an image index Descriptor as a cosign oci.SignedImageIndex, | ||
// allowing access to signatures and attestations stored alongside the image. | ||
SignedImageIndex(context.Context) (cosignoci.SignedImageIndex, error) | ||
} | ||
|
||
// CosignPlaceholderRepo is a placeholder repository name for cosign images. | ||
const CosignPlaceholderRepo = "_cosign" | ||
|
||
type ReferencedImage struct { | ||
Ref name.Reference | ||
Img v1.Image | ||
} | ||
|
||
func NumDescriptorsForCosign(imgs []ReferencedImage) (int64, error) { | ||
descCount := int64(0) | ||
for _, ri := range imgs { | ||
ls, err := ri.Img.Layers() | ||
if err != nil { | ||
return 0, err | ||
} | ||
descCount += int64(len(ls) + 2) | ||
} | ||
return descCount, nil | ||
} | ||
|
||
//nolint:gochecknoglobals | ||
var cosignSuffixes = []string{ | ||
cosignremote.SignatureTagSuffix, | ||
cosignremote.AttestationTagSuffix, | ||
} | ||
|
||
func CosignTag(h v1.Hash, suffix string) string { | ||
return fmt.Sprint(h.Algorithm, "-", h.Hex, ".", suffix) | ||
} | ||
|
||
func CosignRef(imgDigest v1.Hash, imgRef name.Reference, suffix string, opts ...name.Option) (name.Reference, error) { | ||
t := CosignTag(imgDigest, suffix) | ||
repo := CosignPlaceholderRepo | ||
if imgRef != nil { | ||
repo = imgRef.Context().Name() | ||
} | ||
opts = append(opts, name.WithDefaultRegistry("")) | ||
return name.ParseReference(repo+":"+t, opts...) | ||
} |
Oops, something went wrong.