mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 04:17:55 +08:00
feat: add support for oci1.1 cosign signatures(using referrers) (#1963)
- Cosign supports 2 types of signature formats:
1. Using tag -> each new signature of the same manifest is
added as a new layer of the signature manifest having that
specific tag("{alghoritm}-{digest_of_signed_manifest}.sig")
2. Using referrers -> each new signature of the same manifest is
added as a new manifest
- For adding these cosign signature to metadb, we reserved index 0 of the
list of cosign signatures for tag-based signatures. When a new tag-based
signature is added for the same manifest, the element on first position
in its list of cosign signatures(in metadb) will be updated/overwritten.
When a new cosign signature(using referrers) will be added for the same
manifest this new signature will be appended to the list of cosign
signatures.
Signed-off-by: Andreea-Lupu <andreealupu1470@yahoo.com>
This commit is contained in:
+34
-14
@@ -813,7 +813,7 @@ func (bdw *BoltDB) GetMultipleRepoMeta(ctx context.Context, filter func(repoMeta
|
||||
}
|
||||
|
||||
func (bdw *BoltDB) AddManifestSignature(repo string, signedManifestDigest godigest.Digest,
|
||||
sygMeta mTypes.SignatureMetadata,
|
||||
sigMeta mTypes.SignatureMetadata,
|
||||
) error {
|
||||
err := bdw.DB.Update(func(tx *bbolt.Tx) error {
|
||||
repoMetaBuck := tx.Bucket([]byte(RepoMetaBuck))
|
||||
@@ -829,11 +829,11 @@ func (bdw *BoltDB) AddManifestSignature(repo string, signedManifestDigest godige
|
||||
Signatures: map[string]*proto_go.ManifestSignatures{
|
||||
signedManifestDigest.String(): {
|
||||
Map: map[string]*proto_go.SignaturesInfo{
|
||||
sygMeta.SignatureType: {
|
||||
sigMeta.SignatureType: {
|
||||
List: []*proto_go.SignatureInfo{
|
||||
{
|
||||
SignatureManifestDigest: sygMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sygMeta.LayersInfo),
|
||||
SignatureManifestDigest: sigMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sigMeta.LayersInfo),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -867,26 +867,46 @@ func (bdw *BoltDB) AddManifestSignature(repo string, signedManifestDigest godige
|
||||
}
|
||||
|
||||
signatureSlice := &proto_go.SignaturesInfo{List: []*proto_go.SignatureInfo{}}
|
||||
if sigSlice, found := manifestSignatures.Map[sygMeta.SignatureType]; found {
|
||||
if sigSlice, found := manifestSignatures.Map[sigMeta.SignatureType]; found {
|
||||
signatureSlice = sigSlice
|
||||
}
|
||||
|
||||
if !common.ProtoSignatureAlreadyExists(signatureSlice.List, sygMeta) {
|
||||
switch sygMeta.SignatureType {
|
||||
if !common.ProtoSignatureAlreadyExists(signatureSlice.List, sigMeta) {
|
||||
switch sigMeta.SignatureType {
|
||||
case zcommon.NotationSignature:
|
||||
signatureSlice.List = append(signatureSlice.List, &proto_go.SignatureInfo{
|
||||
SignatureManifestDigest: sygMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sygMeta.LayersInfo),
|
||||
SignatureManifestDigest: sigMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sigMeta.LayersInfo),
|
||||
})
|
||||
case zcommon.CosignSignature:
|
||||
signatureSlice.List = []*proto_go.SignatureInfo{{
|
||||
SignatureManifestDigest: sygMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sygMeta.LayersInfo),
|
||||
}}
|
||||
newCosignSig := &proto_go.SignatureInfo{
|
||||
SignatureManifestDigest: sigMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sigMeta.LayersInfo),
|
||||
}
|
||||
|
||||
if zcommon.IsCosignTag(sigMeta.SignatureTag) {
|
||||
// the entry for "sha256-{digest}.sig" signatures should be overwritten if
|
||||
// it exists or added on the first position if it doesn't exist
|
||||
if len(signatureSlice.GetList()) == 0 {
|
||||
signatureSlice.List = []*proto_go.SignatureInfo{newCosignSig}
|
||||
} else {
|
||||
signatureSlice.List[0] = newCosignSig
|
||||
}
|
||||
} else {
|
||||
// the first position should be reserved for "sha256-{digest}.sig" signatures
|
||||
if len(signatureSlice.GetList()) == 0 {
|
||||
signatureSlice.List = []*proto_go.SignatureInfo{{
|
||||
SignatureManifestDigest: "",
|
||||
LayersInfo: []*proto_go.LayersInfo{},
|
||||
}}
|
||||
}
|
||||
|
||||
signatureSlice.List = append(signatureSlice.List, newCosignSig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
manifestSignatures.Map[sygMeta.SignatureType] = signatureSlice
|
||||
manifestSignatures.Map[sigMeta.SignatureType] = signatureSlice
|
||||
protoRepoMeta.Signatures[signedManifestDigest.String()] = manifestSignatures
|
||||
|
||||
return setProtoRepoMeta(protoRepoMeta, repoMetaBuck)
|
||||
|
||||
@@ -1041,7 +1041,7 @@ func (dwr *DynamoDB) UpdateSignaturesValidity(repo string, manifestDigest godige
|
||||
}
|
||||
|
||||
func (dwr *DynamoDB) AddManifestSignature(repo string, signedManifestDigest godigest.Digest,
|
||||
sygMeta mTypes.SignatureMetadata,
|
||||
sigMeta mTypes.SignatureMetadata,
|
||||
) error {
|
||||
protoRepoMeta, err := dwr.getProtoRepoMeta(context.Background(), repo)
|
||||
if err != nil {
|
||||
@@ -1054,11 +1054,11 @@ func (dwr *DynamoDB) AddManifestSignature(repo string, signedManifestDigest godi
|
||||
Signatures: map[string]*proto_go.ManifestSignatures{
|
||||
signedManifestDigest.String(): {
|
||||
Map: map[string]*proto_go.SignaturesInfo{
|
||||
sygMeta.SignatureType: {
|
||||
sigMeta.SignatureType: {
|
||||
List: []*proto_go.SignatureInfo{
|
||||
{
|
||||
SignatureManifestDigest: sygMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sygMeta.LayersInfo),
|
||||
SignatureManifestDigest: sigMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sigMeta.LayersInfo),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1083,26 +1083,46 @@ func (dwr *DynamoDB) AddManifestSignature(repo string, signedManifestDigest godi
|
||||
}
|
||||
|
||||
signatureSlice := &proto_go.SignaturesInfo{List: []*proto_go.SignatureInfo{}}
|
||||
if sigSlice, found := manifestSignatures.Map[sygMeta.SignatureType]; found {
|
||||
if sigSlice, found := manifestSignatures.Map[sigMeta.SignatureType]; found {
|
||||
signatureSlice = sigSlice
|
||||
}
|
||||
|
||||
if !common.ProtoSignatureAlreadyExists(signatureSlice.List, sygMeta) {
|
||||
switch sygMeta.SignatureType {
|
||||
if !common.ProtoSignatureAlreadyExists(signatureSlice.List, sigMeta) {
|
||||
switch sigMeta.SignatureType {
|
||||
case zcommon.NotationSignature:
|
||||
signatureSlice.List = append(signatureSlice.List, &proto_go.SignatureInfo{
|
||||
SignatureManifestDigest: sygMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sygMeta.LayersInfo),
|
||||
SignatureManifestDigest: sigMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sigMeta.LayersInfo),
|
||||
})
|
||||
case zcommon.CosignSignature:
|
||||
signatureSlice.List = []*proto_go.SignatureInfo{{
|
||||
SignatureManifestDigest: sygMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sygMeta.LayersInfo),
|
||||
}}
|
||||
newCosignSig := &proto_go.SignatureInfo{
|
||||
SignatureManifestDigest: sigMeta.SignatureDigest,
|
||||
LayersInfo: mConvert.GetProtoLayersInfo(sigMeta.LayersInfo),
|
||||
}
|
||||
|
||||
if zcommon.IsCosignTag(sigMeta.SignatureTag) {
|
||||
// the entry for "sha256-{digest}.sig" signatures should be overwritten if
|
||||
// it exists or added on the first position if it doesn't exist
|
||||
if len(signatureSlice.GetList()) == 0 {
|
||||
signatureSlice.List = []*proto_go.SignatureInfo{newCosignSig}
|
||||
} else {
|
||||
signatureSlice.List[0] = newCosignSig
|
||||
}
|
||||
} else {
|
||||
// the first position should be reserved for "sha256-{digest}.sig" signatures
|
||||
if len(signatureSlice.GetList()) == 0 {
|
||||
signatureSlice.List = []*proto_go.SignatureInfo{{
|
||||
SignatureManifestDigest: "",
|
||||
LayersInfo: []*proto_go.LayersInfo{},
|
||||
}}
|
||||
}
|
||||
|
||||
signatureSlice.List = append(signatureSlice.List, newCosignSig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
manifestSignatures.Map[sygMeta.SignatureType] = signatureSlice
|
||||
manifestSignatures.Map[sigMeta.SignatureType] = signatureSlice
|
||||
protoRepoMeta.Signatures[signedManifestDigest.String()] = manifestSignatures
|
||||
|
||||
return dwr.setProtoRepoMeta(protoRepoMeta.Name, protoRepoMeta)
|
||||
|
||||
+17
-1
@@ -1290,18 +1290,31 @@ func RunMetaDBTests(t *testing.T, metaDB mTypes.MetaDB, preparationFuncs ...func
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = metaDB.AddManifestSignature(repo1, image1.Digest, mTypes.SignatureMetadata{
|
||||
SignatureType: "cosign",
|
||||
SignatureTag: fmt.Sprintf("sha256-%s.sig", image1.Digest.Encoded()),
|
||||
SignatureDigest: "digesttag",
|
||||
LayersInfo: []mTypes.LayerInfo{{LayerDigest: "layer-digest", LayerContent: []byte{10}}},
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
repoMeta, err := metaDB.GetRepoMeta(ctx, repo1)
|
||||
So(err, ShouldBeNil)
|
||||
So(repoMeta.Signatures[image1.Digest.String()]["cosign"][0].SignatureManifestDigest,
|
||||
ShouldResemble, "digesttag")
|
||||
So(repoMeta.Signatures[image1.Digest.String()]["cosign"][1].SignatureManifestDigest,
|
||||
ShouldResemble, "digest")
|
||||
|
||||
imageMeta, err := metaDB.GetImageMeta(image1.Digest)
|
||||
|
||||
fullImageMeta := convert.GetFullImageMeta(tag1, repoMeta, imageMeta)
|
||||
So(err, ShouldBeNil)
|
||||
So(fullImageMeta.Signatures["cosign"][0].SignatureManifestDigest, ShouldResemble, "digest")
|
||||
So(fullImageMeta.Signatures["cosign"][0].SignatureManifestDigest, ShouldResemble, "digesttag")
|
||||
So(fullImageMeta.Signatures["cosign"][0].LayersInfo[0].LayerDigest, ShouldResemble, "layer-digest")
|
||||
So(fullImageMeta.Signatures["cosign"][0].LayersInfo[0].LayerContent[0], ShouldEqual, 10)
|
||||
So(fullImageMeta.Signatures["cosign"][1].SignatureManifestDigest, ShouldResemble, "digest")
|
||||
So(fullImageMeta.Signatures["cosign"][1].LayersInfo[0].LayerDigest, ShouldResemble, "layer-digest")
|
||||
So(fullImageMeta.Signatures["cosign"][1].LayersInfo[0].LayerContent[0], ShouldEqual, 10)
|
||||
})
|
||||
|
||||
Convey("Test UpdateSignaturesValidity", func() {
|
||||
@@ -1320,6 +1333,7 @@ func RunMetaDBTests(t *testing.T, metaDB mTypes.MetaDB, preparationFuncs ...func
|
||||
err = metaDB.AddManifestSignature(repo1, image1.Digest(), mTypes.SignatureMetadata{
|
||||
SignatureType: "cosign",
|
||||
SignatureDigest: image1.DigestStr(),
|
||||
SignatureTag: fmt.Sprintf("sha256-%s.sig", image1.Digest().Encoded()),
|
||||
LayersInfo: []mTypes.LayerInfo{layerInfo},
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -1442,6 +1456,7 @@ func RunMetaDBTests(t *testing.T, metaDB mTypes.MetaDB, preparationFuncs ...func
|
||||
|
||||
err := metaDB.AddManifestSignature(repo1, image1.Digest(), mTypes.SignatureMetadata{
|
||||
SignatureType: "cosign",
|
||||
SignatureTag: fmt.Sprintf("sha256-%s.sig", image1.Digest().Encoded()),
|
||||
SignatureDigest: "digest",
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
@@ -1467,6 +1482,7 @@ func RunMetaDBTests(t *testing.T, metaDB mTypes.MetaDB, preparationFuncs ...func
|
||||
|
||||
err = metaDB.AddManifestSignature(repo1, image1.Digest(), mTypes.SignatureMetadata{
|
||||
SignatureType: "cosign",
|
||||
SignatureTag: fmt.Sprintf("sha256-%s.sig", image1.Digest().Encoded()),
|
||||
SignatureDigest: "digest",
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
@@ -289,6 +289,7 @@ func SetImageMetaFromInput(ctx context.Context, repo, reference, mediaType strin
|
||||
mTypes.SignatureMetadata{
|
||||
SignatureType: sigType,
|
||||
SignatureDigest: digest.String(),
|
||||
SignatureTag: reference,
|
||||
LayersInfo: layers,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -342,6 +343,11 @@ func isSignature(reference string, manifestContent ispec.Manifest) (bool, string
|
||||
return true, NotationType, manifestContent.Subject.Digest
|
||||
}
|
||||
|
||||
// check cosign signature
|
||||
if manifestArtifactType == zcommon.ArtifactTypeCosign && manifestContent.Subject != nil {
|
||||
return true, CosignType, manifestContent.Subject.Digest
|
||||
}
|
||||
|
||||
if tag := reference; zcommon.IsCosignTag(reference) {
|
||||
prefixLen := len("sha256-")
|
||||
digestLen := 64
|
||||
|
||||
@@ -298,6 +298,7 @@ type SignatureInfo struct {
|
||||
type SignatureMetadata struct {
|
||||
SignatureType string
|
||||
SignatureDigest string
|
||||
SignatureTag string
|
||||
LayersInfo []LayerInfo
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user