Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(meta): add support for uploaded index when signing using notation #1882

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ STACKER := $(shell which stacker)
GOLINTER := $(TOOLSDIR)/bin/golangci-lint
GOLINTER_VERSION := v1.52.2
NOTATION := $(TOOLSDIR)/bin/notation
NOTATION_VERSION := 1.0.0-rc.4
NOTATION_VERSION := 1.0.0
COSIGN := $(TOOLSDIR)/bin/cosign
COSIGN_VERSION := 2.2.0
HELM := $(TOOLSDIR)/bin/helm
Expand Down
4 changes: 2 additions & 2 deletions pkg/api/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5233,7 +5233,7 @@ func TestImageSignatures(t *testing.T) {
So(err, ShouldBeNil)

image := fmt.Sprintf("localhost:%s/%s:%s", port, repoName, "1.0")
err = signature.SignWithNotation("good", image, tdir)
err = signature.SignWithNotation("good", image, tdir, true)
So(err, ShouldBeNil)

err = signature.VerifyWithNotation(image, tdir)
Expand Down Expand Up @@ -7806,7 +7806,7 @@ func TestGCSignaturesAndUntaggedManifestsWithMetaDB(t *testing.T) {
So(err, ShouldBeNil)

// sign the image
err = signature.SignWithNotation("good", image, tdir)
err = signature.SignWithNotation("good", image, tdir, true)
So(err, ShouldBeNil)

// get cosign signature manifest
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/client/image_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func TestSignature(t *testing.T) {
err = UploadImage(CreateDefaultImage(), url, repoName, "0.0.1")
So(err, ShouldBeNil)

err = signature.SignImageUsingNotary("repo7:0.0.1", port)
err = signature.SignImageUsingNotary("repo7:0.0.1", port, true)
So(err, ShouldBeNil)

searchConfig := getTestSearchConfig(url, client.NewSearchService())
Expand Down
9 changes: 9 additions & 0 deletions pkg/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io/fs"
"os"
"regexp"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -119,3 +120,11 @@ func ContainsStringIgnoreCase(strSlice []string, str string) bool {

return false
}

// this function will check if tag is a referrers tag
// (https://github.com/opencontainers/distribution-spec/blob/main/spec.md#referrers-tag-schema).
func IsReferrersTag(tag string) bool {
referrersTagRule := regexp.MustCompile(`sha256\-[A-Za-z0-9]*$`)

return referrersTagRule.MatchString(tag)
}
4 changes: 2 additions & 2 deletions pkg/extensions/extension_image_trust_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[
// sign the image
imageURL := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))

err = signature.SignWithNotation(certName, imageURL, rootDir)
err = signature.SignWithNotation(certName, imageURL, rootDir, true)
So(err, ShouldBeNil)

found, err = test.ReadLogFileAndSearchString(logFile.Name(), "update signatures validity", 10*time.Second)
Expand Down Expand Up @@ -499,7 +499,7 @@ func RunSignatureUploadAndVerificationTests(t *testing.T, cacheDriverParams map[
// sign the image
imageURL := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))

err = signature.SignWithNotation(certName, imageURL, rootDir)
err = signature.SignWithNotation(certName, imageURL, rootDir, false)
So(err, ShouldBeNil)

found, err = test.ReadLogFileAndSearchString(logFile.Name(), "update signatures validity", 10*time.Second)
Expand Down
4 changes: 2 additions & 2 deletions pkg/extensions/imagetrust/image_trust_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ func TestVerifySignatures(t *testing.T) {
// sign the image
image := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))

err = signature.SignWithNotation("notation-sign-test", image, notationDir)
err = signature.SignWithNotation("notation-sign-test", image, notationDir, true)
So(err, ShouldBeNil)

err = test.CopyFiles(path.Join(notationDir, "notation", "truststore"), path.Join(notationDir, "truststore"))
Expand Down Expand Up @@ -1271,7 +1271,7 @@ func RunVerificationTests(t *testing.T, dbDriverParams map[string]interface{}) {
// sign the image
imageURL := fmt.Sprintf("localhost:%s/%s", port, fmt.Sprintf("%s:%s", repo, tag))

err = signature.SignWithNotation(certName, imageURL, notationDir)
err = signature.SignWithNotation(certName, imageURL, notationDir, false)
So(err, ShouldBeNil)

indexContent, err := ctlr.StoreController.DefaultStore.GetIndexContent(repo)
Expand Down
6 changes: 3 additions & 3 deletions pkg/extensions/search/search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4422,7 +4422,7 @@ func TestMetaDBWhenSigningImages(t *testing.T) {
})

Convey("Sign with notation", func() {
err = signature.SignImageUsingNotary("repo1:1.0.1", port)
err = signature.SignImageUsingNotary("repo1:1.0.1", port, true)
So(err, ShouldBeNil)

resp, err := resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(queryImage1))
Expand All @@ -4439,7 +4439,7 @@ func TestMetaDBWhenSigningImages(t *testing.T) {
})

Convey("Sign with notation index", func() {
err = signature.SignImageUsingNotary("repo1:index", port)
err = signature.SignImageUsingNotary("repo1:index", port, false)
So(err, ShouldBeNil)

resp, err := resty.R().Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(queryIndex))
Expand Down Expand Up @@ -5438,7 +5438,7 @@ func TestMetaDBWhenDeletingImages(t *testing.T) {

Convey("Delete a notary signature", func() {
repo := "repo1"
err := signature.SignImageUsingNotary("repo1:1.0.1", port)
err := signature.SignImageUsingNotary("repo1:1.0.1", port, true)
So(err, ShouldBeNil)

query := `
Expand Down
1 change: 1 addition & 0 deletions pkg/extensions/sync/constants/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ const (
Oras = "OrasReference"
Cosign = "CosignSignature"
OCI = "OCIReference"
Tag = "TagReference"
SyncBlobUploadDir = ".sync"
)
6 changes: 2 additions & 4 deletions pkg/extensions/sync/references/cosign.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,8 @@ func (ref CosignReference) SyncReferences(ctx context.Context, localRepo, remote
}

if isSig {
err = ref.metaDB.AddManifestSignature(localRepo, signedManifestDig, mTypes.SignatureMetadata{
SignatureType: sigType,
SignatureDigest: referenceDigest.String(),
})
err = addSigToMeta(ref.metaDB, localRepo, sigType, cosignTag, signedManifestDig, referenceDigest,
manifestBuf, imageStore, ref.log)
} else {
err = meta.SetImageMetaFromInput(localRepo, cosignTag, ispec.MediaTypeImageManifest,
referenceDigest, manifestBuf, ref.storeController.GetImageStore(localRepo),
Expand Down
6 changes: 2 additions & 4 deletions pkg/extensions/sync/references/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,8 @@ func (ref OciReferences) SyncReferences(ctx context.Context, localRepo, remoteRe
}

if isSig {
err = ref.metaDB.AddManifestSignature(localRepo, signedManifestDig, mTypes.SignatureMetadata{
SignatureType: sigType,
SignatureDigest: referenceDigest.String(),
})
err = addSigToMeta(ref.metaDB, localRepo, sigType, referrer.Digest.String(), signedManifestDig, referenceDigest,
referenceBuf, imageStore, ref.log)
} else {
err = meta.SetImageMetaFromInput(localRepo, referenceDigest.String(), referrer.MediaType,
referenceDigest, referenceBuf, ref.storeController.GetImageStore(localRepo),
Expand Down
20 changes: 20 additions & 0 deletions pkg/extensions/sync/references/references.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"zotregistry.io/zot/pkg/common"
client "zotregistry.io/zot/pkg/extensions/sync/httpclient"
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/meta"
mTypes "zotregistry.io/zot/pkg/meta/types"
"zotregistry.io/zot/pkg/storage"
storageTypes "zotregistry.io/zot/pkg/storage/types"
Expand All @@ -42,6 +43,7 @@ func NewReferences(httpClient *client.Client, storeController storage.StoreContr
refs := References{log: log}

refs.referenceList = append(refs.referenceList, NewCosignReference(httpClient, storeController, metaDB, log))
refs.referenceList = append(refs.referenceList, NewTagReferences(httpClient, storeController, metaDB, log))
refs.referenceList = append(refs.referenceList, NewOciReferences(httpClient, storeController, metaDB, log))
refs.referenceList = append(refs.referenceList, NewORASReferences(httpClient, storeController, metaDB, log))

Expand Down Expand Up @@ -215,3 +217,21 @@ func getNotationManifestsFromOCIRefs(ociRefs ispec.Index) []ispec.Descriptor {

return notaryManifests
}

func addSigToMeta(
metaDB mTypes.MetaDB, repo, sigType, tag string, signedManifestDig, referenceDigest godigest.Digest,
referenceBuf []byte, imageStore storageTypes.ImageStore, log log.Logger,
) error {
layersInfo, errGetLayers := meta.GetSignatureLayersInfo(repo, tag, referenceDigest.String(),
sigType, referenceBuf, imageStore, log)

if errGetLayers != nil {
return errGetLayers
}

return metaDB.AddManifestSignature(repo, signedManifestDig, mTypes.SignatureMetadata{
SignatureType: sigType,
SignatureDigest: referenceDigest.String(),
LayersInfo: layersInfo,
})
}
59 changes: 59 additions & 0 deletions pkg/extensions/sync/references/references_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,54 @@ func TestOci(t *testing.T) {
})
}

func TestReferrersTag(t *testing.T) {
Convey("trigger errors", t, func() {
cfg := client.Config{
URL: "url",
TLSVerify: false,
}

client, err := client.New(cfg, log.NewLogger("debug", ""))
So(err, ShouldBeNil)

referrersTag := NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
return []byte{}, "", "", errRef
},
}}, nil, log.NewLogger("debug", ""))

ok := referrersTag.IsSigned(context.Background(), "repo", "")
So(ok, ShouldBeFalse)

// trigger GetImageManifest err
ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "digest")
So(err, ShouldNotBeNil)
So(ok, ShouldBeFalse)

referrersTag = NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
return []byte{}, "", "", zerr.ErrManifestNotFound
},
}}, nil, log.NewLogger("debug", ""))

// trigger GetImageManifest err
ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "digest")
So(err, ShouldBeNil)
So(ok, ShouldBeFalse)

referrersTag = NewTagReferences(client, storage.StoreController{DefaultStore: mocks.MockedImageStore{
GetImageManifestFn: func(repo, reference string) ([]byte, godigest.Digest, string, error) {
return []byte{}, "digest", "", nil
},
}}, nil, log.NewLogger("debug", ""))

// different digest
ok, err = referrersTag.canSkipReferences("repo", "subjectdigest", "newdigest")
So(err, ShouldBeNil)
So(ok, ShouldBeFalse)
})
}

func TestORAS(t *testing.T) {
Convey("trigger errors", t, func() {
cfg := client.Config{
Expand Down Expand Up @@ -392,3 +440,14 @@ func TestCompareArtifactRefs(t *testing.T) {
}
})
}

func TestAddSigToMeta(t *testing.T) {
Convey("Test addSigToMeta", t, func() {
imageStore := mocks.MockedImageStore{}
metaDB := mocks.MetaDBMock{}

err := addSigToMeta(metaDB, "repo", "cosign", "tag", godigest.FromString("signedmanifest"),
godigest.FromString("reference"), []byte("bad"), imageStore, log.Logger{})
So(err, ShouldNotBeNil)
})
}
Loading