Repository: deislabs/ratify (go)

Issue:
Update the `github.com/spdx/tools-golang`dependency to `v0.5.0`. 
### What would you like to be added?

Currently, Ratify uses tools-golang v0.3.0. The most recent release is v0.5.0. This version has support for SPDX 2.3. 

The Kubernetes BOM tool now generates SPDX 2.3 documents and it would be useful to be able to support them. 

### Anything else you would like to add?

_No response_

### Are you willing to submit PRs to contribute to this feature?

- [X] Yes, I am willing to implement it.

Pull request description:
chore: Bump spdx tools-golang to 0.5.0 and associated refactor
# Description

## What this PR does / why we need it:
<!--Please include a summary of the changes and relevant context. -->

## Which issue(s) this PR fixes *(optional, using `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when the PR gets merged)*:
Fixes #766 

## Type of change

This PR bumps the SPDX tools-golang dependency to 0.5.0.  This adds support for SPDX 2.3. The upstream library has undergone some refactoring so this PR includes some changes to match the new upstream library. 

I also added a test to the json sbom parser to verify it could load a valid JSON spdx file and would return an error when parsing an invalid spdx json file (missing version). 

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Helm Chart Change (any edit/addition/update that is necessary for changes merged to the `main` branch)
- [ ] This change requires a documentation update

# How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

- [x] Added TestProcessSPDXJsonMediaType
- [x] Added TestProcessInvalidSPDXJsonMediaType
- [x] Ran existing tests in spdxutils_test.go 

# Checklist:

- [x] Does the affected code have corresponding tests?
- [ ] Are the changes documented, not just with inline documentation, but also with conceptual documentation such as an overview of a new feature, or task-based documentation like a tutorial? Consider if this change should be announced on your project blog.
- [ ] Does this introduce breaking changes that would require an announcement or bumping the major version?
- [x] Do all new files have appropriate license header?

# Post Merge Requirements
- [ ] MAINTAINERS: manually trigger the "Publish Package" workflow after merging any PR that indicates `Helm Chart Change`


Patch:
diff --git a/.gitignore b/.gitignore
index faf2826..53bc1e8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,6 @@ certs/
 .vscode/settings.json
 
 .staging
+
+pkg/referrerstore/factory/plugin-store
+
diff --git a/go.mod b/go.mod
index fd97ae2..19e5057 100644
--- a/go.mod
+++ b/go.mod
@@ -31,7 +31,7 @@ require (
 	github.com/sigstore/cosign v1.13.1
 	github.com/sigstore/sigstore v1.4.6
 	github.com/sirupsen/logrus v1.9.0
-	github.com/spdx/tools-golang v0.3.0
+	github.com/spdx/tools-golang v0.5.0
 	github.com/spf13/cobra v1.6.1
 	github.com/xlab/treeprint v1.1.0
 	go.opentelemetry.io/otel/exporters/prometheus v0.37.0
@@ -66,6 +66,7 @@ require (
 	github.com/alibabacloud-go/tea-utils v1.4.4 // indirect
 	github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
 	github.com/aliyun/credentials-go v1.2.3 // indirect
+	github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
 	github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect
 	github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20220228164355-396b2034c795 // indirect
 	github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect
diff --git a/go.sum b/go.sum
index f1949c6..f1b525d 100644
--- a/go.sum
+++ b/go.sum
@@ -180,6 +180,8 @@ github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCE
 github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
 github.com/aliyun/credentials-go v1.2.3 h1:Vmodnr52Rz1mcbwn0kzMhLRKb6soizewuKXdfZiNemU=
 github.com/aliyun/credentials-go v1.2.3/go.mod h1:/KowD1cfGSLrLsH28Jr8W+xwoId0ywIy5lNzDz6O1vw=
+github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
+github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
@@ -1018,8 +1020,8 @@ github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
 github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=
-github.com/spdx/tools-golang v0.3.0 h1:rtm+DHk3aAt74Fh0Wgucb4pCxjXV8SqHCPEb2iBd30k=
-github.com/spdx/tools-golang v0.3.0/go.mod h1:RO4Y3IFROJnz+43JKm1YOrbtgQNljW4gAPpA/sY2eqo=
+github.com/spdx/tools-golang v0.5.0 h1:/fqihV2Jna7fmow65dHpgKNsilgLK7ICpd2tkCnPEyY=
+github.com/spdx/tools-golang v0.5.0/go.mod h1:kkGlrSXXfHwuSzHQZJRV3aKu9ZXCq/MSf2+xyiJH1lM=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
diff --git a/plugins/verifier/licensechecker/utils/spdxutils.go b/plugins/verifier/licensechecker/utils/spdxutils.go
index 153d4e2..02423b7 100644
--- a/plugins/verifier/licensechecker/utils/spdxutils.go
+++ b/plugins/verifier/licensechecker/utils/spdxutils.go
@@ -19,16 +19,16 @@ import (
 	"strings"
 
 	"github.com/spdx/tools-golang/spdx"
-	"github.com/spdx/tools-golang/tvloader"
+	"github.com/spdx/tools-golang/tagvalue"
 )
 
-func BlobToSPDX(bytes []byte) (*spdx.Document2_2, error) {
+func BlobToSPDX(bytes []byte) (*spdx.Document, error) {
 	raw := string(bytes)
 	reader := strings.NewReader(raw)
-	return tvloader.Load2_2(reader)
+	return tagvalue.Read(reader)
 }
 
-func GetPackageLicenses(doc spdx.Document2_2) []PackageLicense {
+func GetPackageLicenses(doc spdx.Document) []PackageLicense {
 	output := []PackageLicense{}
 	for _, p := range doc.Packages {
 		output = append(output, PackageLicense{
diff --git a/plugins/verifier/sbom/sbom.go b/plugins/verifier/sbom/sbom.go
index dfcd0cf..1d10a4e 100644
--- a/plugins/verifier/sbom/sbom.go
+++ b/plugins/verifier/sbom/sbom.go
@@ -16,6 +16,7 @@ limitations under the License.
 package main
 
 import (
+	"bytes"
 	"context"
 	"encoding/json"
 	"fmt"
@@ -29,7 +30,7 @@ import (
 	"github.com/deislabs/ratify/pkg/verifier"
 	"github.com/deislabs/ratify/pkg/verifier/plugin/skel"
 
-	"github.com/spdx/tools-golang/jsonloader/parser2v2"
+	jsonLoader "github.com/spdx/tools-golang/json"
 )
 
 // PluginConfig describes the configuration of the sbom verifier
@@ -108,7 +109,7 @@ func VerifyReference(args *skel.CmdArgs, subjectReference common.Reference, refe
 }
 
 func processSpdxJsonMediaType(name string, refBlob []byte) (*verifier.VerifierResult, error) {
-	if doc, err := parser2v2.Load2_2(refBlob); doc != nil {
+	if doc, err := jsonLoader.Read(bytes.NewReader(refBlob)); doc != nil {
 		return &verifier.VerifierResult{
 			Name:       name,
 			IsSuccess:  true,


Test patch:
diff --git a/plugins/verifier/licensechecker/utils/spdxutils_test.go b/plugins/verifier/licensechecker/utils/spdxutils_test.go
index f17130d..db6711e 100644
--- a/plugins/verifier/licensechecker/utils/spdxutils_test.go
+++ b/plugins/verifier/licensechecker/utils/spdxutils_test.go
@@ -46,7 +46,7 @@ func TestBlobToSPDX(t *testing.T) {
 		t.Fatalf("could not parse SPDX doc from bytes")
 	}
 	expected := "localhost-5000/test-v1"
-	result := spdxDoc.CreationInfo.DocumentName
+	result := spdxDoc.DocumentName
 	if expected != result {
 		t.Fatalf("expected: %s, got: %s", expected, result)
 	}
diff --git a/plugins/verifier/sbom/sbom_test.go b/plugins/verifier/sbom/sbom_test.go
new file mode 100644
index 0000000..bce1a0b
--- /dev/null
+++ b/plugins/verifier/sbom/sbom_test.go
@@ -0,0 +1,46 @@
+/*
+Copyright The Ratify Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package main
+
+import (
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func TestProcessSPDXJsonMediaType(t *testing.T) {
+	b, err := os.ReadFile(filepath.Join("testdata", "bom.json"))
+	if err != nil {
+		t.Fatalf("error reading %s", filepath.Join("testdata", "bom.json"))
+	}
+	vr, err := processSpdxJsonMediaType("test", b)
+	if err != nil {
+		t.Fatalf("expected to process spdx json file: %s", filepath.Join("testdata", "bom.json"))
+	}
+	if !vr.IsSuccess {
+		t.Fatalf("expected to successfully verify schema")
+	}
+}
+
+func TestProcessInvalidSPDXJsonMediaType(t *testing.T) {
+	b, err := os.ReadFile(filepath.Join("testdata", "invalid-bom.json"))
+	if err != nil {
+		t.Fatalf("error reading %s", filepath.Join("testdata", "invalid-bom.json"))
+	}
+	_, err = processSpdxJsonMediaType("test", b)
+	if err == nil {
+		t.Fatalf("expected to have an error processing spdx json file: %s", filepath.Join("testdata", "bom.json"))
+	}
+}
diff --git a/plugins/verifier/sbom/testdata/bom.json b/plugins/verifier/sbom/testdata/bom.json
new file mode 100644
index 0000000..2c07841
--- /dev/null
+++ b/plugins/verifier/sbom/testdata/bom.json
@@ -0,0 +1,99 @@
+{
+    "SPDXID": "SPDXRef-DOCUMENT",
+    "name": "SBOM-SPDX-7d465ef1-69aa-4b69-9957-3e5f8ace888f",
+    "spdxVersion": "SPDX-2.3",
+    "creationInfo": {
+      "created": "2023-04-11T16:42:56Z",
+      "creators": [
+        "Tool: bom-v0.5.1"
+      ],
+      "licenseListVersion": "3.20"
+    },
+    "dataLicense": "CC0-1.0",
+    "documentNamespace": "https://spdx.org/spdxdocs/k8s-releng-bom-69a90f8a-decc-4678-b8da-a61e0cfdb74d",
+    "documentDescribes": [
+      "SPDXRef-Package-demo2"
+    ],
+    "files": [
+      {
+        "SPDXID": "SPDXRef-File-demo2-go.mod",
+        "fileName": "go.mod",
+        "copyrightText": "NOASSERTION",
+        "fileTypes": [
+          "OTHER"
+        ],
+        "licenseInfoInFiles": [
+          "NONE"
+        ],
+        "checksums": [
+          {
+            "algorithm": "SHA256",
+            "checksumValue": "556a93d912a114b04ceb8187ebbf8395680cda467e08ac0080952932f3c370e2"
+          },
+          {
+            "algorithm": "SHA512",
+            "checksumValue": "c4f0d7f2838d18dd8fc96eff38535889522768b62da194348e6c672953a8979b2783f9d5aaead2ee4ff2067b7d788cbcdfd13bb9a446c16e7c60993a2b16860e"
+          },
+          {
+            "algorithm": "SHA1",
+            "checksumValue": "194215c6bfae739a649b92b28d1cc583b5fa99ef"
+          }
+        ]
+      },
+      {
+        "SPDXID": "SPDXRef-File-demo2-main.go",
+        "fileName": "main.go",
+        "copyrightText": "NOASSERTION",
+        "fileTypes": [
+          "SOURCE"
+        ],
+        "licenseInfoInFiles": [
+          "NONE"
+        ],
+        "checksums": [
+          {
+            "algorithm": "SHA512",
+            "checksumValue": "77ec79541bb49829bab859367eeb8fd11948cdc634754136049285a02c95e66ff56f2006804b2b7070732148431697d6a8feb13fd07aebef4041c30c20882780"
+          },
+          {
+            "algorithm": "SHA1",
+            "checksumValue": "c34d7fea5f9c09e6e876e4f98c0d1ca30babe034"
+          },
+          {
+            "algorithm": "SHA256",
+            "checksumValue": "fc3c41bf3de8295fc920f7da4ed98e3772bf5a849cc335722d6e33b405160908"
+          }
+        ]
+      }
+    ],
+    "packages": [
+      {
+        "SPDXID": "SPDXRef-Package-demo2",
+        "name": "demo2",
+        "versionInfo": "",
+        "filesAnalyzed": true,
+        "downloadLocation": "NONE",
+        "copyrightText": "NOASSERTION",
+        "hasFiles": [
+          "SPDXRef-File-demo2-main.go",
+          "SPDXRef-File-demo2-go.mod"
+        ],
+        "checksums": [],
+        "packageVerificationCode": {
+          "packageVerificationCodeValue": "34ac7b8817933e27e7bfad817f7e757b57c1a9e8"
+        }
+      }
+    ],
+    "relationships": [
+      {
+        "spdxElementId": "SPDXRef-Package-demo2",
+        "relationshipType": "CONTAINS",
+        "relatedSpdxElement": "SPDXRef-File-demo2-main.go"
+      },
+      {
+        "spdxElementId": "SPDXRef-Package-demo2",
+        "relationshipType": "CONTAINS",
+        "relatedSpdxElement": "SPDXRef-File-demo2-go.mod"
+      }
+    ]
+  }
\ No newline at end of file
diff --git a/plugins/verifier/sbom/testdata/invalid-bom.json b/plugins/verifier/sbom/testdata/invalid-bom.json
new file mode 100644
index 0000000..0fbec2a
--- /dev/null
+++ b/plugins/verifier/sbom/testdata/invalid-bom.json
@@ -0,0 +1,98 @@
+{
+    "SPDXID": "SPDXRef-DOCUMENT",
+    "name": "SBOM-SPDX-7d465ef1-69aa-4b69-9957-3e5f8ace888f",
+    "creationInfo": {
+      "created": "2023-04-11T16:42:56Z",
+      "creators": [
+        "Tool: bom-v0.5.1"
+      ],
+      "licenseListVersion": "3.20"
+    },
+    "dataLicense": "CC0-1.0",
+    "documentNamespace": "https://spdx.org/spdxdocs/k8s-releng-bom-69a90f8a-decc-4678-b8da-a61e0cfdb74d",
+    "documentDescribes": [
+      "SPDXRef-Package-demo2"
+    ],
+    "files": [
+      {
+        "SPDXID": "SPDXRef-File-demo2-go.mod",
+        "fileName": "go.mod",
+        "copyrightText": "NOASSERTION",
+        "fileTypes": [
+          "OTHER"
+        ],
+        "licenseInfoInFiles": [
+          "NONE"
+        ],
+        "checksums": [
+          {
+            "algorithm": "SHA256",
+            "checksumValue": "556a93d912a114b04ceb8187ebbf8395680cda467e08ac0080952932f3c370e2"
+          },
+          {
+            "algorithm": "SHA512",
+            "checksumValue": "c4f0d7f2838d18dd8fc96eff38535889522768b62da194348e6c672953a8979b2783f9d5aaead2ee4ff2067b7d788cbcdfd13bb9a446c16e7c60993a2b16860e"
+          },
+          {
+            "algorithm": "SHA1",
+            "checksumValue": "194215c6bfae739a649b92b28d1cc583b5fa99ef"
+          }
+        ]
+      },
+      {
+        "SPDXID": "SPDXRef-File-demo2-main.go",
+        "fileName": "main.go",
+        "copyrightText": "NOASSERTION",
+        "fileTypes": [
+          "SOURCE"
+        ],
+        "licenseInfoInFiles": [
+          "NONE"
+        ],
+        "checksums": [
+          {
+            "algorithm": "SHA512",
+            "checksumValue": "77ec79541bb49829bab859367eeb8fd11948cdc634754136049285a02c95e66ff56f2006804b2b7070732148431697d6a8feb13fd07aebef4041c30c20882780"
+          },
+          {
+            "algorithm": "SHA1",
+            "checksumValue": "c34d7fea5f9c09e6e876e4f98c0d1ca30babe034"
+          },
+          {
+            "algorithm": "SHA256",
+            "checksumValue": "fc3c41bf3de8295fc920f7da4ed98e3772bf5a849cc335722d6e33b405160908"
+          }
+        ]
+      }
+    ],
+    "packages": [
+      {
+        "SPDXID": "SPDXRef-Package-demo2",
+        "name": "demo2",
+        "versionInfo": "",
+        "filesAnalyzed": true,
+        "downloadLocation": "NONE",
+        "copyrightText": "NOASSERTION",
+        "hasFiles": [
+          "SPDXRef-File-demo2-main.go",
+          "SPDXRef-File-demo2-go.mod"
+        ],
+        "checksums": [],
+        "packageVerificationCode": {
+          "packageVerificationCodeValue": "34ac7b8817933e27e7bfad817f7e757b57c1a9e8"
+        }
+      }
+    ],
+    "relationships": [
+      {
+        "spdxElementId": "SPDXRef-Package-demo2",
+        "relationshipType": "CONTAINS",
+        "relatedSpdxElement": "SPDXRef-File-demo2-main.go"
+      },
+      {
+        "spdxElementId": "SPDXRef-Package-demo2",
+        "relationshipType": "CONTAINS",
+        "relatedSpdxElement": "SPDXRef-File-demo2-go.mod"
+      }
+    ]
+  }
\ No newline at end of file