mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 15:50:15 -08:00
fix(sbom): use Annotation instead of AttributionTexts for SPDX formats (#7811)
This commit is contained in:
39
integration/testdata/conda-spdx.json.golden
vendored
39
integration/testdata/conda-spdx.json.golden
vendored
@@ -31,10 +31,15 @@
|
||||
"referenceLocator": "pkg:conda/openssl@1.1.1q"
|
||||
}
|
||||
],
|
||||
"attributionTexts": [
|
||||
"PkgType: conda-pkg"
|
||||
],
|
||||
"primaryPackagePurpose": "LIBRARY"
|
||||
"primaryPackagePurpose": "LIBRARY",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgType: conda-pkg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "pip",
|
||||
@@ -55,20 +60,30 @@
|
||||
"referenceLocator": "pkg:conda/pip@22.2.2"
|
||||
}
|
||||
],
|
||||
"attributionTexts": [
|
||||
"PkgType: conda-pkg"
|
||||
],
|
||||
"primaryPackagePurpose": "LIBRARY"
|
||||
"primaryPackagePurpose": "LIBRARY",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgType: conda-pkg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "testdata/fixtures/repo/conda",
|
||||
"SPDXID": "SPDXRef-Filesystem-2e2426fd0f2580ef",
|
||||
"downloadLocation": "NONE",
|
||||
"filesAnalyzed": false,
|
||||
"attributionTexts": [
|
||||
"SchemaVersion: 2"
|
||||
],
|
||||
"primaryPackagePurpose": "SOURCE"
|
||||
"primaryPackagePurpose": "SOURCE",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "SchemaVersion: 2"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"files": [
|
||||
|
||||
93
integration/testdata/julia-spdx.json.golden
vendored
93
integration/testdata/julia-spdx.json.golden
vendored
@@ -17,11 +17,21 @@
|
||||
"SPDXID": "SPDXRef-Application-18fc3597717a3e56",
|
||||
"downloadLocation": "NONE",
|
||||
"filesAnalyzed": false,
|
||||
"attributionTexts": [
|
||||
"Class: lang-pkgs",
|
||||
"Type: julia"
|
||||
],
|
||||
"primaryPackagePurpose": "APPLICATION"
|
||||
"primaryPackagePurpose": "APPLICATION",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "Class: lang-pkgs"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "Type: julia"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "A",
|
||||
@@ -40,11 +50,21 @@
|
||||
"referenceLocator": "pkg:julia/A@1.9.0?uuid=ead4f63c-334e-11e9-00e6-e7f0a5f21b60"
|
||||
}
|
||||
],
|
||||
"attributionTexts": [
|
||||
"PkgID: ead4f63c-334e-11e9-00e6-e7f0a5f21b60",
|
||||
"PkgType: julia"
|
||||
],
|
||||
"primaryPackagePurpose": "LIBRARY"
|
||||
"primaryPackagePurpose": "LIBRARY",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgID: ead4f63c-334e-11e9-00e6-e7f0a5f21b60"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgType: julia"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "B",
|
||||
@@ -63,11 +83,21 @@
|
||||
"referenceLocator": "pkg:julia/B@1.9.0?uuid=f41f7b98-334e-11e9-1257-49272045fb24"
|
||||
}
|
||||
],
|
||||
"attributionTexts": [
|
||||
"PkgID: f41f7b98-334e-11e9-1257-49272045fb24",
|
||||
"PkgType: julia"
|
||||
],
|
||||
"primaryPackagePurpose": "LIBRARY"
|
||||
"primaryPackagePurpose": "LIBRARY",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgID: f41f7b98-334e-11e9-1257-49272045fb24"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgType: julia"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "B",
|
||||
@@ -86,21 +116,36 @@
|
||||
"referenceLocator": "pkg:julia/B@1.9.0?uuid=edca9bc6-334e-11e9-3554-9595dbb4349c"
|
||||
}
|
||||
],
|
||||
"attributionTexts": [
|
||||
"PkgID: edca9bc6-334e-11e9-3554-9595dbb4349c",
|
||||
"PkgType: julia"
|
||||
],
|
||||
"primaryPackagePurpose": "LIBRARY"
|
||||
"primaryPackagePurpose": "LIBRARY",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgID: edca9bc6-334e-11e9-3554-9595dbb4349c"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "PkgType: julia"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "testdata/fixtures/repo/julia",
|
||||
"SPDXID": "SPDXRef-Filesystem-1be792dd0077c431",
|
||||
"downloadLocation": "NONE",
|
||||
"filesAnalyzed": false,
|
||||
"attributionTexts": [
|
||||
"SchemaVersion: 2"
|
||||
],
|
||||
"primaryPackagePurpose": "SOURCE"
|
||||
"primaryPackagePurpose": "SOURCE",
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2021-08-25T12:20:30Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "SchemaVersion: 2"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
|
||||
@@ -50,6 +50,8 @@ const (
|
||||
PackageSupplierNoAssertion = "NOASSERTION"
|
||||
PackageSupplierOrganization = "Organization"
|
||||
|
||||
PackageAnnotatorToolField = "Tool"
|
||||
|
||||
RelationShipContains = common.TypeRelationshipContains
|
||||
RelationShipDescribe = common.TypeRelationshipDescribe
|
||||
RelationShipDependsOn = common.TypeRelationshipDependsOn
|
||||
@@ -122,6 +124,9 @@ func (m *Marshaler) Marshal(ctx context.Context, bom *core.BOM) (*spdx.Document,
|
||||
packages []*spdx.Package
|
||||
)
|
||||
|
||||
// Lock time to use same time for all spdx fields
|
||||
timeNow := clock.Now(ctx).UTC().Format(time.RFC3339)
|
||||
|
||||
root := bom.Root()
|
||||
pkgDownloadLocation := m.packageDownloadLocation(root)
|
||||
|
||||
@@ -129,7 +134,7 @@ func (m *Marshaler) Marshal(ctx context.Context, bom *core.BOM) (*spdx.Document,
|
||||
packageIDs := make(map[uuid.UUID]spdx.ElementID)
|
||||
|
||||
// Root package contains OS, OS packages, language-specific packages and so on.
|
||||
rootPkg, err := m.rootSPDXPackage(root, pkgDownloadLocation)
|
||||
rootPkg, err := m.rootSPDXPackage(root, timeNow, pkgDownloadLocation)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to generate a root package: %w", err)
|
||||
}
|
||||
@@ -144,7 +149,7 @@ func (m *Marshaler) Marshal(ctx context.Context, bom *core.BOM) (*spdx.Document,
|
||||
if c.Root {
|
||||
continue
|
||||
}
|
||||
spdxPackage, err := m.spdxPackage(c, pkgDownloadLocation)
|
||||
spdxPackage, err := m.spdxPackage(c, timeNow, pkgDownloadLocation)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("spdx package error: %w", err)
|
||||
}
|
||||
@@ -216,7 +221,7 @@ func (m *Marshaler) Marshal(ctx context.Context, bom *core.BOM) (*spdx.Document,
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
Created: clock.Now(ctx).UTC().Format(time.RFC3339),
|
||||
Created: timeNow,
|
||||
},
|
||||
Packages: packages,
|
||||
Relationships: relationShips,
|
||||
@@ -237,7 +242,7 @@ func (m *Marshaler) packageDownloadLocation(root *core.Component) string {
|
||||
return location
|
||||
}
|
||||
|
||||
func (m *Marshaler) rootSPDXPackage(root *core.Component, pkgDownloadLocation string) (*spdx.Package, error) {
|
||||
func (m *Marshaler) rootSPDXPackage(root *core.Component, timeNow, pkgDownloadLocation string) (*spdx.Package, error) {
|
||||
var externalReferences []*spdx.PackageExternalReference
|
||||
// When the target is a container image, add PURL to the external references of the root package.
|
||||
if root.PkgIdentifier.PURL != nil {
|
||||
@@ -258,17 +263,25 @@ func (m *Marshaler) rootSPDXPackage(root *core.Component, pkgDownloadLocation st
|
||||
PackageName: root.Name,
|
||||
PackageSPDXIdentifier: elementID(camelCase(string(root.Type)), pkgID),
|
||||
PackageDownloadLocation: pkgDownloadLocation,
|
||||
PackageAttributionTexts: m.spdxAttributionTexts(root),
|
||||
Annotations: m.spdxAnnotations(root, timeNow),
|
||||
PackageExternalReferences: externalReferences,
|
||||
PrimaryPackagePurpose: pkgPurpose,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Marshaler) appendAttributionText(attributionTexts []string, key, value string) []string {
|
||||
func (m *Marshaler) appendAnnotation(annotations []spdx.Annotation, timeNow, key, value string) []spdx.Annotation {
|
||||
if value == "" {
|
||||
return attributionTexts
|
||||
return annotations
|
||||
}
|
||||
return append(attributionTexts, fmt.Sprintf("%s: %s", key, value))
|
||||
return append(annotations, spdx.Annotation{
|
||||
AnnotationDate: timeNow,
|
||||
AnnotationType: spdx.CategoryOther,
|
||||
Annotator: spdx.Annotator{
|
||||
Annotator: fmt.Sprintf("%s-%s", CreatorTool, m.appVersion),
|
||||
AnnotatorType: PackageAnnotatorToolField,
|
||||
},
|
||||
AnnotationComment: fmt.Sprintf("%s: %s", key, value),
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Marshaler) purlExternalReference(packageURL string) *spdx.PackageExternalReference {
|
||||
@@ -287,7 +300,7 @@ func (m *Marshaler) advisoryExternalReference(primaryURL string) *spdx.PackageEx
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Marshaler) spdxPackage(c *core.Component, pkgDownloadLocation string) (spdx.Package, error) {
|
||||
func (m *Marshaler) spdxPackage(c *core.Component, timeNow, pkgDownloadLocation string) (spdx.Package, error) {
|
||||
pkgID, err := calcPkgID(m.hasher, c)
|
||||
if err != nil {
|
||||
return spdx.Package{}, xerrors.Errorf("failed to get os metadata package ID: %w", err)
|
||||
@@ -343,7 +356,7 @@ func (m *Marshaler) spdxPackage(c *core.Component, pkgDownloadLocation string) (
|
||||
PrimaryPackagePurpose: purpose,
|
||||
PackageDownloadLocation: pkgDownloadLocation,
|
||||
PackageExternalReferences: pkgExtRefs,
|
||||
PackageAttributionTexts: m.spdxAttributionTexts(c),
|
||||
Annotations: m.spdxAnnotations(c, timeNow),
|
||||
PackageSourceInfo: sourceInfo,
|
||||
PackageSupplier: supplier,
|
||||
PackageChecksums: m.spdxChecksums(digests),
|
||||
@@ -365,16 +378,15 @@ func spdxPkgName(component *core.Component) string {
|
||||
}
|
||||
return component.Name
|
||||
}
|
||||
|
||||
func (m *Marshaler) spdxAttributionTexts(c *core.Component) []string {
|
||||
var texts []string
|
||||
func (m *Marshaler) spdxAnnotations(c *core.Component, timeNow string) []spdx.Annotation {
|
||||
var annotations []spdx.Annotation
|
||||
for _, p := range c.Properties {
|
||||
// Add properties that are not in other fields.
|
||||
if !slices.Contains(duplicateProperties, p.Name) {
|
||||
texts = m.appendAttributionText(texts, p.Name, p.Value)
|
||||
annotations = m.appendAnnotation(annotations, timeNow, p.Name, p.Value)
|
||||
}
|
||||
}
|
||||
return texts
|
||||
return annotations
|
||||
}
|
||||
|
||||
func (m *Marshaler) spdxLicense(c *core.Component) string {
|
||||
|
||||
@@ -25,6 +25,20 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/uuid"
|
||||
)
|
||||
|
||||
func annotation(t *testing.T, comment string) spdx.Annotation {
|
||||
t.Helper()
|
||||
|
||||
return spdx.Annotation{
|
||||
AnnotationDate: "2021-08-25T12:20:30Z",
|
||||
AnnotationType: spdx.CategoryOther,
|
||||
Annotator: spdx.Annotator{
|
||||
Annotator: "trivy-0.56.2",
|
||||
AnnotatorType: tspdx.PackageAnnotatorToolField,
|
||||
},
|
||||
AnnotationComment: comment,
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshaler_Marshal(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -164,7 +178,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -176,9 +190,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "app/Gemfile.lock",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: lang-pkgs",
|
||||
"Type: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: lang-pkgs"),
|
||||
annotation(t, "Type: bundler"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -186,9 +200,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "app/subproject/Gemfile.lock",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: lang-pkgs",
|
||||
"Type: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: lang-pkgs"),
|
||||
annotation(t, "Type: bundler"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -202,14 +216,14 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
Locator: "pkg:oci/rails@sha256%3Aa27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177?arch=arm64&repository_url=index.docker.io%2Flibrary%2Frails",
|
||||
},
|
||||
},
|
||||
PackageAttributionTexts: []string{
|
||||
"DiffID: sha256:d871dadfb37b53ef1ca45be04fc527562b91989991a8f545345ae3be0b93f92a",
|
||||
"ImageID: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
|
||||
"Labels:vendor: aquasecurity",
|
||||
"RepoDigest: rails@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177",
|
||||
"RepoTag: rails:latest",
|
||||
"SchemaVersion: 2",
|
||||
"Size: 1024",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "DiffID: sha256:d871dadfb37b53ef1ca45be04fc527562b91989991a8f545345ae3be0b93f92a"),
|
||||
annotation(t, "ImageID: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6"),
|
||||
annotation(t, "Labels:vendor: aquasecurity"),
|
||||
annotation(t, "RepoDigest: rails@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177"),
|
||||
annotation(t, "RepoTag: rails:latest"),
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
annotation(t, "Size: 1024"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeContainer,
|
||||
},
|
||||
@@ -220,8 +234,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageVersion: "7.0.1",
|
||||
PackageLicenseConcluded: "NOASSERTION",
|
||||
PackageLicenseDeclared: "NOASSERTION",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: bundler"),
|
||||
},
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference{
|
||||
{
|
||||
@@ -241,8 +255,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageVersion: "7.0.1",
|
||||
PackageLicenseConcluded: "NOASSERTION",
|
||||
PackageLicenseDeclared: "NOASSERTION",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: bundler"),
|
||||
},
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference{
|
||||
{
|
||||
@@ -262,8 +276,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageVersion: "7.0.1",
|
||||
PackageLicenseConcluded: "NOASSERTION",
|
||||
PackageLicenseDeclared: "NOASSERTION",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: bundler"),
|
||||
},
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference{
|
||||
{
|
||||
@@ -283,8 +297,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageVersion: "2.30-93.el8",
|
||||
PackageLicenseConcluded: "GPL-3.0-or-later",
|
||||
PackageLicenseDeclared: "GPL-3.0-or-later",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: centos",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: centos"),
|
||||
},
|
||||
PackageSupplier: &spdx.Supplier{
|
||||
SupplierType: tspdx.PackageSupplierOrganization,
|
||||
@@ -312,9 +326,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageName: "centos",
|
||||
PackageVersion: "8.3.2011",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeOS,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: os-pkgs",
|
||||
"Type: centos",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: os-pkgs"),
|
||||
annotation(t, "Type: centos"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -486,7 +500,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -497,11 +511,11 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageName: "centos:latest",
|
||||
PackageSPDXIdentifier: "ContainerImage-413bfede37ad01fc",
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageAttributionTexts: []string{
|
||||
"ImageID: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
|
||||
"RepoTag: centos:latest",
|
||||
"SchemaVersion: 2",
|
||||
"Size: 1024",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "ImageID: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6"),
|
||||
annotation(t, "RepoTag: centos:latest"),
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
annotation(t, "Size: 1024"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeContainer,
|
||||
},
|
||||
@@ -512,8 +526,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageVersion: "1:2.2.53-1.el8",
|
||||
PackageLicenseConcluded: "GPL-2.0-or-later",
|
||||
PackageLicenseDeclared: "GPL-2.0-or-later",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: centos",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: centos"),
|
||||
},
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference{
|
||||
{
|
||||
@@ -546,9 +560,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
Locator: "pkg:gem/actionpack@7.0.1",
|
||||
},
|
||||
},
|
||||
PackageAttributionTexts: []string{
|
||||
"LayerDiffID: sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488",
|
||||
"PkgType: gemspec",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "LayerDiffID: sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488"),
|
||||
annotation(t, "PkgType: gemspec"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
@@ -571,9 +585,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
Locator: "pkg:gem/actionpack@7.0.1",
|
||||
},
|
||||
},
|
||||
PackageAttributionTexts: []string{
|
||||
"LayerDiffID: sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488",
|
||||
"PkgType: gemspec",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "LayerDiffID: sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488"),
|
||||
annotation(t, "PkgType: gemspec"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
@@ -588,9 +602,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageName: "centos",
|
||||
PackageVersion: "8.3.2011",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeOS,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: os-pkgs",
|
||||
"Type: centos",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: os-pkgs"),
|
||||
annotation(t, "Type: centos"),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -719,7 +733,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -731,9 +745,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "Gemfile.lock",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: lang-pkgs",
|
||||
"Type: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: lang-pkgs"),
|
||||
annotation(t, "Type: bundler"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -741,9 +755,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "pom.xml",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: lang-pkgs",
|
||||
"Type: pom",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: lang-pkgs"),
|
||||
annotation(t, "Type: pom"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -763,8 +777,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
PackageSourceInfo: "package found in: Gemfile.lock",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: bundler",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: bundler"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -784,17 +798,17 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
PackageSourceInfo: "package found in: pom.xml",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgID: com.example:example:1.0.0",
|
||||
"PkgType: pom",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgID: com.example:example:1.0.0"),
|
||||
annotation(t, "PkgType: pom"),
|
||||
},
|
||||
},
|
||||
{
|
||||
PackageSPDXIdentifier: spdx.ElementID("Filesystem-5af0f1f08c20909a"),
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "masahiro331/CVE-2021-41098",
|
||||
PackageAttributionTexts: []string{
|
||||
"SchemaVersion: 2",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
||||
},
|
||||
@@ -878,7 +892,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -906,16 +920,16 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: jar",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: jar"),
|
||||
},
|
||||
},
|
||||
{
|
||||
PackageSPDXIdentifier: spdx.ElementID("Filesystem-121e7e7a43f02ab"),
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "log4j-core-2.17.0.jar",
|
||||
PackageAttributionTexts: []string{
|
||||
"SchemaVersion: 2",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
||||
},
|
||||
@@ -980,7 +994,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -1001,9 +1015,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
Locator: "pkg:npm/ruby-typeprof@0.20.1",
|
||||
},
|
||||
},
|
||||
PackageAttributionTexts: []string{
|
||||
"LayerDiffID: sha256:661c3fd3cc16b34c070f3620ca6b03b6adac150f9a7e5d0e3c707a159990f88e",
|
||||
"PkgType: node-pkg",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "LayerDiffID: sha256:661c3fd3cc16b34c070f3620ca6b03b6adac150f9a7e5d0e3c707a159990f88e"),
|
||||
annotation(t, "PkgType: node-pkg"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
@@ -1016,8 +1030,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageSPDXIdentifier: "Repository-1a78857c1a6a759e",
|
||||
PackageName: "http://test-aggregate",
|
||||
PackageDownloadLocation: "git+http://test-aggregate",
|
||||
PackageAttributionTexts: []string{
|
||||
"SchemaVersion: 2",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
||||
},
|
||||
@@ -1075,7 +1089,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -1086,8 +1100,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageName: "empty/path",
|
||||
PackageSPDXIdentifier: "Filesystem-70f34983067dba86",
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageAttributionTexts: []string{
|
||||
"SchemaVersion: 2",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
||||
},
|
||||
@@ -1137,7 +1151,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -1148,8 +1162,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageName: "secret",
|
||||
PackageSPDXIdentifier: "Filesystem-5c08d34162a2c5d3",
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageAttributionTexts: []string{
|
||||
"SchemaVersion: 2",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
||||
},
|
||||
@@ -1209,7 +1223,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
CreatorType: "Organization",
|
||||
},
|
||||
{
|
||||
Creator: "trivy-0.38.1",
|
||||
Creator: "trivy-0.56.2",
|
||||
CreatorType: "Tool",
|
||||
},
|
||||
},
|
||||
@@ -1221,9 +1235,9 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageName: "/usr/local/bin/test",
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
||||
PackageAttributionTexts: []string{
|
||||
"Class: lang-pkgs",
|
||||
"Type: gobinary",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "Class: lang-pkgs"),
|
||||
annotation(t, "Type: gobinary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1235,8 +1249,8 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
PackageSourceInfo: "package found in: /usr/local/bin/test",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: gobinary",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: gobinary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1256,16 +1270,16 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
||||
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
||||
PackageSourceInfo: "package found in: /usr/local/bin/test",
|
||||
PackageAttributionTexts: []string{
|
||||
"PkgType: gobinary",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "PkgType: gobinary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
PackageName: "go-artifact",
|
||||
PackageSPDXIdentifier: "Filesystem-e340f27468b382be",
|
||||
PackageDownloadLocation: "NONE",
|
||||
PackageAttributionTexts: []string{
|
||||
"SchemaVersion: 2",
|
||||
Annotations: []spdx.Annotation{
|
||||
annotation(t, "SchemaVersion: 2"),
|
||||
},
|
||||
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
||||
},
|
||||
@@ -1326,7 +1340,7 @@ func TestMarshaler_Marshal(t *testing.T) {
|
||||
ctx := clock.With(context.Background(), time.Date(2021, 8, 25, 12, 20, 30, 5, time.UTC))
|
||||
uuid.SetFakeUUID(t, "3ff14136-e09f-4df9-80ea-%012d")
|
||||
|
||||
marshaler := tspdx.NewMarshaler("0.38.1", tspdx.WithHasher(hasher))
|
||||
marshaler := tspdx.NewMarshaler("0.56.2", tspdx.WithHasher(hasher))
|
||||
spdxDoc, err := marshaler.MarshalReport(ctx, tc.inputReport)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
98
pkg/sbom/spdx/testdata/happy/bom.json
vendored
98
pkg/sbom/spdx/testdata/happy/bom.json
vendored
@@ -37,13 +37,43 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-ContainerImage-b5d81cde5f95c8fc",
|
||||
"attributionTexts": [
|
||||
"SchemaVersion: 2",
|
||||
"ImageID: sha256:49193a2310dbad4c02382da87ac624a80a92387a4f7536235f9ba590e5bcd7b5",
|
||||
"DiffID: sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3",
|
||||
"DiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1",
|
||||
"RepoTag: maven-test-project:latest",
|
||||
"RepoTag: tmp-test:latest"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "SchemaVersion: 2"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "ImageID: sha256:49193a2310dbad4c02382da87ac624a80a92387a4f7536235f9ba590e5bcd7b5"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "DiffID: sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "DiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "RepoTag: maven-test-project:latest"
|
||||
},
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "RepoTag: tmp-test:latest"
|
||||
}
|
||||
],
|
||||
"filesAnalyzed": false,
|
||||
"name": "meven-test-project"
|
||||
@@ -56,8 +86,13 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-Package-2906575950df652b",
|
||||
"attributionTexts": [
|
||||
"LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
}
|
||||
],
|
||||
"externalRefs": [
|
||||
{
|
||||
@@ -74,8 +109,13 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-Package-2a53baa495b9ddaf",
|
||||
"attributionTexts": [
|
||||
"LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
}
|
||||
],
|
||||
"externalRefs": [
|
||||
{
|
||||
@@ -92,8 +132,13 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-Package-5e2e255ac76747ef",
|
||||
"attributionTexts": [
|
||||
"LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
}
|
||||
],
|
||||
"externalRefs": [
|
||||
{
|
||||
@@ -110,8 +155,13 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-Package-5f1dbaff8de5eb06",
|
||||
"attributionTexts": [
|
||||
"LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
}
|
||||
],
|
||||
"externalRefs": [
|
||||
{
|
||||
@@ -128,8 +178,13 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-Package-84ebffe38343d949",
|
||||
"attributionTexts": [
|
||||
"LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "LayerDiffID: sha256:3c79e832b1b4891a1cb4a326ef8524e0bd14a2537150ac0e203a5677176c1ca1"
|
||||
}
|
||||
],
|
||||
"externalRefs": [
|
||||
{
|
||||
@@ -146,8 +201,13 @@
|
||||
},
|
||||
{
|
||||
"SPDXID": "SPDXRef-Package-b7ebaf0233f1ef7b",
|
||||
"attributionTexts": [
|
||||
"LayerDiffID: sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3"
|
||||
"annotations": [
|
||||
{
|
||||
"annotator": "Tool: trivy-dev",
|
||||
"annotationDate": "2024-10-29T06:50:38Z",
|
||||
"annotationType": "OTHER",
|
||||
"comment": "LayerDiffID: sha256:dd565ff850e7003356e2b252758f9bdc1ff2803f61e995e24c7844f6297f8fc3"
|
||||
}
|
||||
],
|
||||
"externalRefs": [
|
||||
{
|
||||
|
||||
@@ -194,9 +194,21 @@ func (s *SPDX) parsePackage(spdxPkg spdx.Package) (*core.Component, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Attributions
|
||||
for _, attr := range spdxPkg.PackageAttributionTexts {
|
||||
k, v, ok := strings.Cut(attr, ": ")
|
||||
// Trivy stores properties in Annotations
|
||||
// But previous versions stored properties in AttributionTexts
|
||||
// So we need to check both cases to maintain backward compatibility
|
||||
var props []string
|
||||
if len(spdxPkg.Annotations) > 0 {
|
||||
for _, annotation := range spdxPkg.Annotations {
|
||||
props = append(props, annotation.AnnotationComment)
|
||||
}
|
||||
} else if len(spdxPkg.PackageAttributionTexts) > 0 {
|
||||
for _, attr := range spdxPkg.PackageAttributionTexts {
|
||||
props = append(props, attr)
|
||||
}
|
||||
}
|
||||
for _, prop := range props {
|
||||
k, v, ok := strings.Cut(prop, ": ")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user