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 diff --git a/bindings-go/apis/v2/signatures/normalise.go b/bindings-go/apis/v2/signatures/normalise.go index 5897d4c0..69a76bd7 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) @@ -104,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 } @@ -132,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) } @@ -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..3fc28153 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 := "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"}]},{"meta":[{"schemaVersion":"v2"}]}] + //[{"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{ @@ -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"}), + }, }, }, } @@ -94,6 +120,32 @@ 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 & Resource empty -> should be left out completely from normalisation + 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{