From 441d0d7b8492d18591da733fcd0d360131461c14 Mon Sep 17 00:00:00 2001 From: Johannes Schicktanz Date: Fri, 1 Jul 2022 08:54:37 +0200 Subject: [PATCH 1/4] remove schema version and empty lists from normalisation --- bindings-go/apis/v2/signatures/normalise.go | 15 +++++----- .../apis/v2/signatures/normalise_test.go | 29 +++++++++++++++++-- bindings-go/apis/v2/signatures/sign_test.go | 2 +- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/bindings-go/apis/v2/signatures/normalise.go b/bindings-go/apis/v2/signatures/normalise.go index 5897d4c0..91433159 100644 --- a/bindings-go/apis/v2/signatures/normalise.go +++ b/bindings-go/apis/v2/signatures/normalise.go @@ -86,10 +86,6 @@ func normaliseComponentDescriptor(cd cdv2.ComponentDescriptor) ([]byte, error) { return nil, fmt.Errorf("component descriptor %s:%s is not normaliseable: %w", cd.Name, cd.Version, err) } - meta := []Entry{ - {"schemaVersion": cd.Metadata.Version}, - } - componentReferences := []interface{}{} for _, ref := range cd.ComponentSpec.ComponentReferences { extraIdentity := buildExtraIdentity(ref.ExtraIdentity) @@ -148,12 +144,17 @@ func normaliseComponentDescriptor(cd cdv2.ComponentDescriptor) ([]byte, error) { {"name": cd.ComponentSpec.Name}, {"version": cd.ComponentSpec.Version}, {"provider": cd.ComponentSpec.Provider}, - {"componentReferences": componentReferences}, - {"resources": resources}, + } + + if len(componentReferences) > 0 { + componentSpec = append(componentSpec, Entry{"componentReferences": componentReferences}) + } + + if len(resources) > 0 { + componentSpec = append(componentSpec, Entry{"resources": resources}) } normalisedComponentDescriptor := []Entry{ - {"meta": meta}, {"component": componentSpec}, } diff --git a/bindings-go/apis/v2/signatures/normalise_test.go b/bindings-go/apis/v2/signatures/normalise_test.go index d3ddfb1a..c24ba592 100644 --- a/bindings-go/apis/v2/signatures/normalise_test.go +++ b/bindings-go/apis/v2/signatures/normalise_test.go @@ -26,9 +26,9 @@ import ( var _ = Describe("Normalise/Hash component-descriptor", func() { var baseCd cdv2.ComponentDescriptor - correctBaseCdHash := "6c571bb6e351ae755baa7f26cbd1f600d2968ab8b88e25a3bab277e53afdc3ad" + correctBaseCdHash := "d0508c87df2aca0deb423598d54dca5af290796632193199d38dc85054c8b4f8" //corresponding normalised CD: - //[{"component":[{"componentReferences":[[{"componentName":"compRefNameComponentName"},{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"jsonNormalisation/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"refKey":"refName"}]},{"name":"compRefName"},{"version":"v0.0.2compRef"}]]},{"name":"CD-Name"},{"provider":""},{"resources":[[{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"key":"value"}]},{"name":"Resource1"},{"relation": ""},{"type",""},{"version":"v0.0.3resource"}]]},{"version":"v0.0.1"}]},{"meta":[{"schemaVersion":"v2"}]}] + //[{"component":[{"componentReferences":[[{"componentName":"compRefNameComponentName"},{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"jsonNormalisation/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"refKey":"refName"}]},{"name":"compRefName"},{"version":"v0.0.2compRef"}]]},{"name":"CD-Name"},{"provider":""},{"resources":[[{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"key":"value"}]},{"name":"Resource1"},{"relation": ""},{"type",""},{"version":"v0.0.3resource"}]]},{"version":"v0.0.1"}]}]}] BeforeEach(func() { baseCd = cdv2.ComponentDescriptor{ Metadata: cdv2.Metadata{ @@ -94,6 +94,31 @@ var _ = Describe("Normalise/Hash component-descriptor", func() { Expect(hash.Value).To(Equal(correctBaseCdHash)) }) }) + Describe("should remove empty component refs/resources lists during normalisation", func() { + It("with sha256", func() { + expectedHash := "44460fad9d46f9281018858a94bf80ae348e5c24ea4d9955ade89a16fb587edf" + //corresponding normalised CD: + //[{"component":[{"name":"CD-Name"},{"provider":""},{"version":"v0.0.1"}]}] + cdWithEmptyLists := cdv2.ComponentDescriptor{ + Metadata: cdv2.Metadata{ + Version: "v2", + }, + ComponentSpec: cdv2.ComponentSpec{ + ObjectMeta: cdv2.ObjectMeta{ + Name: "CD-Name", + Version: "v0.0.1", + }, + ComponentReferences: []cdv2.ComponentReference{}, + Resources: []cdv2.Resource{}, + }, + } + hasher, err := signatures.HasherForName(signatures.SHA256) + Expect(err).To(BeNil()) + hash, err := signatures.HashForComponentDescriptor(cdWithEmptyLists, *hasher) + Expect(err).To(BeNil()) + Expect(hash.Value).To(Equal(expectedHash)) + }) + }) Describe("should ignore modifications in unhashed fields", func() { It("should succeed with signature changes", func() { baseCd.Signatures = append(baseCd.Signatures, cdv2.Signature{ diff --git a/bindings-go/apis/v2/signatures/sign_test.go b/bindings-go/apis/v2/signatures/sign_test.go index ebb34ff4..520b1a2f 100644 --- a/bindings-go/apis/v2/signatures/sign_test.go +++ b/bindings-go/apis/v2/signatures/sign_test.go @@ -52,7 +52,7 @@ var _ = Describe("Sign/Verify component-descriptor", func() { AlgorithmName: signatures.SHA256, } signatureName := "testSignatureName" - correctBaseCdHash := "6c571bb6e351ae755baa7f26cbd1f600d2968ab8b88e25a3bab277e53afdc3ad" + correctBaseCdHash := "d0508c87df2aca0deb423598d54dca5af290796632193199d38dc85054c8b4f8" BeforeEach(func() { baseCd = cdv2.ComponentDescriptor{ From f90d736d2d82ce7d736ec28d067d2ffc911a34a1 Mon Sep 17 00:00:00 2001 From: Johannes Schicktanz Date: Fri, 1 Jul 2022 09:14:15 +0200 Subject: [PATCH 2/4] add .vscode to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ca1042c5..ffb9f09a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ __pycache__/ .pytest_cache/ .DS_Store .idea +.vscode bindings-go/vendor From 6d0059eabd1cd219cea7944002a914bd19ed7cec Mon Sep 17 00:00:00 2001 From: Johannes Schicktanz Date: Fri, 1 Jul 2022 09:15:40 +0200 Subject: [PATCH 3/4] remove extra identity from normalisation if empty --- bindings-go/apis/v2/signatures/normalise.go | 34 +++++++++---------- .../apis/v2/signatures/normalise_test.go | 29 +++++++++++++++- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/bindings-go/apis/v2/signatures/normalise.go b/bindings-go/apis/v2/signatures/normalise.go index 91433159..69a76bd7 100644 --- a/bindings-go/apis/v2/signatures/normalise.go +++ b/bindings-go/apis/v2/signatures/normalise.go @@ -100,25 +100,32 @@ func normaliseComponentDescriptor(cd cdv2.ComponentDescriptor) ([]byte, error) { {"componentName": ref.ComponentName}, {"name": ref.Name}, {"version": ref.Version}, - {"extraIdentity": extraIdentity}, {"digest": digest}, } + + if extraIdentity != nil { + componentReference = append(componentReference, Entry{"extraIdentity": extraIdentity}) + } + componentReferences = append(componentReferences, componentReference) } resources := []interface{}{} for _, res := range cd.ComponentSpec.Resources { + resource := []Entry{ + {"name": res.Name}, + {"version": res.Version}, + {"type": res.Type}, + {"relation": res.Relation}, + } + extraIdentity := buildExtraIdentity(res.ExtraIdentity) + if extraIdentity != nil { + resource = append(resource, Entry{"extraIdentity": extraIdentity}) + } - //ignore access.type=None for normalisation and hash calculation + // skip adding digest for access.type=None -> ignore for normalisation and hash calculation if res.Access == nil || res.Access.Type == "None" { - resource := []Entry{ - {"name": res.Name}, - {"version": res.Version}, - {"type": res.Type}, - {"relation": res.Relation}, - {"extraIdentity": extraIdentity}, - } resources = append(resources, resource) continue } @@ -128,15 +135,8 @@ func normaliseComponentDescriptor(cd cdv2.ComponentDescriptor) ([]byte, error) { {"normalisationAlgorithm": res.Digest.NormalisationAlgorithm}, {"value": res.Digest.Value}, } + resource = append(resource, Entry{"digest": digest}) - resource := []Entry{ - {"name": res.Name}, - {"version": res.Version}, - {"type": res.Type}, - {"relation": res.Relation}, - {"extraIdentity": extraIdentity}, - {"digest": digest}, - } resources = append(resources, resource) } diff --git a/bindings-go/apis/v2/signatures/normalise_test.go b/bindings-go/apis/v2/signatures/normalise_test.go index c24ba592..0535868a 100644 --- a/bindings-go/apis/v2/signatures/normalise_test.go +++ b/bindings-go/apis/v2/signatures/normalise_test.go @@ -26,7 +26,7 @@ import ( var _ = Describe("Normalise/Hash component-descriptor", func() { var baseCd cdv2.ComponentDescriptor - correctBaseCdHash := "d0508c87df2aca0deb423598d54dca5af290796632193199d38dc85054c8b4f8" + correctBaseCdHash := "aa32547cf0cbead58bc9a27d6c0545d6a4965f9ff2de9f09ce1e6d777f53fbaf" //corresponding normalised CD: //[{"component":[{"componentReferences":[[{"componentName":"compRefNameComponentName"},{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"jsonNormalisation/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"refKey":"refName"}]},{"name":"compRefName"},{"version":"v0.0.2compRef"}]]},{"name":"CD-Name"},{"provider":""},{"resources":[[{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"key":"value"}]},{"name":"Resource1"},{"relation": ""},{"type",""},{"version":"v0.0.3resource"}]]},{"version":"v0.0.1"}]}]}] BeforeEach(func() { @@ -53,6 +53,17 @@ var _ = Describe("Normalise/Hash component-descriptor", func() { Value: "00000000000000", }, }, + { + // ExtraIdentity is nil -> should be left out completely from normalisation + Name: "compRefWithNoExtraIdentity", + ComponentName: "compRefNameComponentName", + Version: "v0.0.3compRef", + Digest: &cdv2.DigestSpec{ + HashAlgorithm: signatures.SHA256, + NormalisationAlgorithm: string(cdv2.JsonNormalisationV1), + Value: "00000000000000", + }, + }, }, Resources: []cdv2.Resource{ { @@ -70,6 +81,21 @@ var _ = Describe("Normalise/Hash component-descriptor", func() { }, Access: cdv2.NewUnstructuredType(cdv2.OCIRegistryType, map[string]interface{}{"imageRef": "ref"}), }, + { + IdentityObjectMeta: cdv2.IdentityObjectMeta{ + Name: "ResourceWithNoExtraIdentity", + Version: "v0.0.4resource", + ExtraIdentity: cdv2.Identity{ + "key": "value", + }, + }, + Digest: &cdv2.DigestSpec{ + HashAlgorithm: signatures.SHA256, + NormalisationAlgorithm: string(cdv2.OciArtifactDigestV1), + Value: "00000000000000", + }, + Access: cdv2.NewUnstructuredType(cdv2.OCIRegistryType, map[string]interface{}{"imageRef": "ref:v0.0.4"}), + }, }, }, } @@ -108,6 +134,7 @@ var _ = Describe("Normalise/Hash component-descriptor", func() { Name: "CD-Name", Version: "v0.0.1", }, + // ComponentReferences & Resource empty -> should be left out completely from normalisation ComponentReferences: []cdv2.ComponentReference{}, Resources: []cdv2.Resource{}, }, From 5af714decd893775022eb4d87825533fc9e24964 Mon Sep 17 00:00:00 2001 From: Johannes Schicktanz Date: Fri, 1 Jul 2022 09:22:13 +0200 Subject: [PATCH 4/4] update example normalised cd --- bindings-go/apis/v2/signatures/normalise_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings-go/apis/v2/signatures/normalise_test.go b/bindings-go/apis/v2/signatures/normalise_test.go index 0535868a..3fc28153 100644 --- a/bindings-go/apis/v2/signatures/normalise_test.go +++ b/bindings-go/apis/v2/signatures/normalise_test.go @@ -28,7 +28,7 @@ var _ = Describe("Normalise/Hash component-descriptor", func() { var baseCd cdv2.ComponentDescriptor correctBaseCdHash := "aa32547cf0cbead58bc9a27d6c0545d6a4965f9ff2de9f09ce1e6d777f53fbaf" //corresponding normalised CD: - //[{"component":[{"componentReferences":[[{"componentName":"compRefNameComponentName"},{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"jsonNormalisation/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"refKey":"refName"}]},{"name":"compRefName"},{"version":"v0.0.2compRef"}]]},{"name":"CD-Name"},{"provider":""},{"resources":[[{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"key":"value"}]},{"name":"Resource1"},{"relation": ""},{"type",""},{"version":"v0.0.3resource"}]]},{"version":"v0.0.1"}]}]}] + //[{"component":[{"componentReferences":[[{"componentName":"compRefNameComponentName"},{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"jsonNormalisation/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"refKey":"refName"}]},{"name":"compRefName"},{"version":"v0.0.2compRef"}],[{"componentName":"compRefNameComponentName"},{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"jsonNormalisation/v1"},{"value":"00000000000000"}]},{"name":"compRefWithNoExtraIdentity"},{"version":"v0.0.3compRef"}]]},{"name":"CD-Name"},{"provider":""},{"resources":[[{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"key":"value"}]},{"name":"Resource1"},{"relation":""},{"type":""},{"version":"v0.0.3resource"}],[{"digest":[{"hashAlgorithm":"sha256"},{"normalisationAlgorithm":"ociArtifactDigest/v1"},{"value":"00000000000000"}]},{"extraIdentity":[{"key":"value"}]},{"name":"ResourceWithNoExtraIdentity"},{"relation":""},{"type":""},{"version":"v0.0.4resource"}]]},{"version":"v0.0.1"}]}] BeforeEach(func() { baseCd = cdv2.ComponentDescriptor{ Metadata: cdv2.Metadata{