mirror of
https://github.com/aquasecurity/trivy.git
synced 2026-01-31 13:53:14 +08:00
1496 lines
50 KiB
Go
1496 lines
50 KiB
Go
package spdx_test
|
|
|
|
import (
|
|
"context"
|
|
"hash/fnv"
|
|
"testing"
|
|
"time"
|
|
|
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
"github.com/mitchellh/hashstructure/v2"
|
|
"github.com/package-url/packageurl-go"
|
|
"github.com/spdx/tools-golang/spdx"
|
|
"github.com/spdx/tools-golang/spdx/v2/common"
|
|
"github.com/spdx/tools-golang/spdxlib"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/aquasecurity/trivy/pkg/clock"
|
|
"github.com/aquasecurity/trivy/pkg/fanal/artifact"
|
|
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
|
"github.com/aquasecurity/trivy/pkg/report"
|
|
"github.com/aquasecurity/trivy/pkg/sbom/core"
|
|
tspdx "github.com/aquasecurity/trivy/pkg/sbom/spdx"
|
|
"github.com/aquasecurity/trivy/pkg/types"
|
|
"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
|
|
inputReport types.Report
|
|
wantSBOM *spdx.Document
|
|
}{
|
|
{
|
|
name: "happy path for container scan",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "rails:latest",
|
|
ArtifactType: artifact.TypeContainerImage,
|
|
Metadata: types.Metadata{
|
|
Size: 1024,
|
|
OS: &ftypes.OS{
|
|
Family: ftypes.CentOS,
|
|
Name: "8.3.2011",
|
|
Eosl: true,
|
|
},
|
|
ImageID: "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
|
|
RepoTags: []string{"rails:latest"},
|
|
DiffIDs: []string{"sha256:d871dadfb37b53ef1ca45be04fc527562b91989991a8f545345ae3be0b93f92a"},
|
|
RepoDigests: []string{"rails@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177"},
|
|
ImageConfig: v1.ConfigFile{
|
|
Architecture: "arm64",
|
|
Config: v1.Config{
|
|
Labels: map[string]string{
|
|
"vendor": "aquasecurity",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Results: types.Results{
|
|
{
|
|
Target: "rails:latest (centos 8.3.2011)",
|
|
Class: types.ClassOSPkg,
|
|
Type: ftypes.CentOS,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "binutils",
|
|
Version: "2.30",
|
|
Release: "93.el8",
|
|
Epoch: 0,
|
|
Arch: "aarch64",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "F4C10A4371C93487",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeRPM,
|
|
Namespace: "centos",
|
|
Name: "binutils",
|
|
Version: "2.30-93.el8",
|
|
Qualifiers: packageurl.Qualifiers{
|
|
{
|
|
Key: "arch",
|
|
Value: "aarch64",
|
|
},
|
|
{
|
|
Key: "distro",
|
|
Value: "centos-8.3.2011",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
SrcName: "binutils",
|
|
SrcVersion: "2.30",
|
|
SrcRelease: "93.el8",
|
|
SrcEpoch: 0,
|
|
Modularitylabel: "",
|
|
Licenses: []string{"GPLv3+"},
|
|
Maintainer: "CentOS",
|
|
Digest: "md5:7459cec61bb4d1b0ca8107e25e0dd005",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Target: "app/subproject/Gemfile.lock",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.Bundler,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "B1A9DE534F2737AF",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGem,
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "actioncontroller",
|
|
Version: "7.0.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "1628B51BD543965D",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGem,
|
|
Name: "actioncontroller",
|
|
Version: "7.0.1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Target: "app/Gemfile.lock",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.Bundler,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "92D6B6D3FF6F8FF5",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGem,
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "rails:latest",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/container_image/rails:latest-3ff14136-e09f-4df9-80ea-000000000009",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Application-9f48cdd13858abaf"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "app/Gemfile.lock",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: lang-pkgs"),
|
|
annotation(t, "Type: bundler"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Application-692290f4b2235359"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "app/subproject/Gemfile.lock",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: lang-pkgs"),
|
|
annotation(t, "Type: bundler"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("ContainerImage-9396d894cd0cb6cb"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "rails:latest",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:oci/rails@sha256%3Aa27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177?arch=arm64&repository_url=index.docker.io%2Flibrary%2Frails",
|
|
},
|
|
},
|
|
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,
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-b8d4663e6d412e7"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "actioncontroller",
|
|
PackageVersion: "7.0.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: bundler"),
|
|
},
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:gem/actioncontroller@7.0.1",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: app/subproject/Gemfile.lock",
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-3b51e821f6796568"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "actionpack",
|
|
PackageVersion: "7.0.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: bundler"),
|
|
},
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:gem/actionpack@7.0.1",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: app/subproject/Gemfile.lock",
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-fb5630bc7d55a21c"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "actionpack",
|
|
PackageVersion: "7.0.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: bundler"),
|
|
},
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:gem/actionpack@7.0.1",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: app/Gemfile.lock",
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-5d43902b18ed2e2c"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "binutils",
|
|
PackageVersion: "2.30-93.el8",
|
|
PackageLicenseConcluded: "GPL-3.0-or-later",
|
|
PackageLicenseDeclared: "GPL-3.0-or-later",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: centos"),
|
|
},
|
|
PackageSupplier: &spdx.Supplier{
|
|
SupplierType: tspdx.PackageSupplierOrganization,
|
|
Supplier: "CentOS",
|
|
},
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:rpm/centos/binutils@2.30-93.el8?arch=aarch64&distro=centos-8.3.2011",
|
|
},
|
|
},
|
|
PackageSourceInfo: "built package from: binutils 2.30-93.el8",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageChecksums: []common.Checksum{
|
|
{
|
|
Algorithm: common.MD5,
|
|
Value: "7459cec61bb4d1b0ca8107e25e0dd005",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("OperatingSystem-20f7fa3049cc748c"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "centos",
|
|
PackageVersion: "8.3.2011",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeOS,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: os-pkgs"),
|
|
annotation(t, "Type: centos"),
|
|
},
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-692290f4b2235359"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-3b51e821f6796568"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-692290f4b2235359"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-b8d4663e6d412e7"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-9f48cdd13858abaf"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-fb5630bc7d55a21c"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "ContainerImage-9396d894cd0cb6cb"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Application-692290f4b2235359"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "ContainerImage-9396d894cd0cb6cb"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Application-9f48cdd13858abaf"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "ContainerImage-9396d894cd0cb6cb"},
|
|
RefB: spdx.DocElementID{ElementRefID: "OperatingSystem-20f7fa3049cc748c"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "ContainerImage-9396d894cd0cb6cb"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "OperatingSystem-20f7fa3049cc748c"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-5d43902b18ed2e2c"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
OtherLicenses: nil,
|
|
Annotations: nil,
|
|
Reviews: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "happy path for local container scan",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "centos:latest",
|
|
ArtifactType: artifact.TypeContainerImage,
|
|
Metadata: types.Metadata{
|
|
Size: 1024,
|
|
OS: &ftypes.OS{
|
|
Family: ftypes.CentOS,
|
|
Name: "8.3.2011",
|
|
Eosl: true,
|
|
},
|
|
ImageID: "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
|
|
RepoTags: []string{"centos:latest"},
|
|
RepoDigests: []string{},
|
|
ImageConfig: v1.ConfigFile{
|
|
Architecture: "arm64",
|
|
},
|
|
},
|
|
Results: types.Results{
|
|
{
|
|
Target: "centos:latest (centos 8.3.2011)",
|
|
Class: types.ClassOSPkg,
|
|
Type: ftypes.CentOS,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "acl",
|
|
Version: "2.2.53",
|
|
Release: "1.el8",
|
|
Epoch: 1,
|
|
Arch: "aarch64",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "740219943F17B1DF",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeRPM,
|
|
Namespace: "centos",
|
|
Name: "acl",
|
|
Version: "2.2.53-1.el8",
|
|
Qualifiers: packageurl.Qualifiers{
|
|
{
|
|
Key: "arch",
|
|
Value: "aarch64",
|
|
},
|
|
{
|
|
Key: "distro",
|
|
Value: "centos-8.3.2011",
|
|
},
|
|
{
|
|
Key: "epoch",
|
|
Value: "1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
SrcName: "acl",
|
|
SrcVersion: "2.2.53",
|
|
SrcRelease: "1.el8",
|
|
SrcEpoch: 1,
|
|
Modularitylabel: "",
|
|
Licenses: []string{"GPLv2+"},
|
|
Digest: "md5:483792b8b5f9eb8be7dc4407733118d0",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Target: "Ruby",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.GemSpec,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "E8DB2C6E35F8B990",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGem,
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
},
|
|
},
|
|
Layer: ftypes.Layer{
|
|
DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488",
|
|
},
|
|
FilePath: "tools/project-john/specifications/actionpack.gemspec",
|
|
Digest: "sha1:d2f9f9aed5161f6e4116a3f9573f41cd832f137c",
|
|
},
|
|
{
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "B3E70B2159CFAC50",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGem,
|
|
Name: "actionpack",
|
|
Version: "7.0.1",
|
|
},
|
|
},
|
|
Layer: ftypes.Layer{
|
|
DiffID: "sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488",
|
|
},
|
|
FilePath: "tools/project-doe/specifications/actionpack.gemspec",
|
|
Digest: "sha1:413f98442c83808042b5d1d2611a346b999bdca5",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "centos:latest",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/container_image/centos:latest-3ff14136-e09f-4df9-80ea-000000000006",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageName: "centos:latest",
|
|
PackageSPDXIdentifier: "ContainerImage-413bfede37ad01fc",
|
|
PackageDownloadLocation: "NONE",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "ImageID: sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6"),
|
|
annotation(t, "RepoTag: centos:latest"),
|
|
annotation(t, "SchemaVersion: 2"),
|
|
annotation(t, "Size: 1024"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeContainer,
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-40c4059fe08523bf"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "acl",
|
|
PackageVersion: "1:2.2.53-1.el8",
|
|
PackageLicenseConcluded: "GPL-2.0-or-later",
|
|
PackageLicenseDeclared: "GPL-2.0-or-later",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: centos"),
|
|
},
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:rpm/centos/acl@2.2.53-1.el8?arch=aarch64&distro=centos-8.3.2011&epoch=1",
|
|
},
|
|
},
|
|
PackageSourceInfo: "built package from: acl 1:2.2.53-1.el8",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageChecksums: []common.Checksum{
|
|
{
|
|
Algorithm: common.MD5,
|
|
Value: "483792b8b5f9eb8be7dc4407733118d0",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-69f68dd639314edd"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "actionpack",
|
|
PackageVersion: "7.0.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:gem/actionpack@7.0.1",
|
|
},
|
|
},
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "LayerDiffID: sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488"),
|
|
annotation(t, "PkgType: gemspec"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
FilesAnalyzed: true,
|
|
PackageVerificationCode: &spdx.PackageVerificationCode{
|
|
Value: "688d98e7e5660b879fd1fc548af8c0df3b7d785a",
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-da2cda24d2ecbfe6"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "actionpack",
|
|
PackageVersion: "7.0.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:gem/actionpack@7.0.1",
|
|
},
|
|
},
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "LayerDiffID: sha256:ccb64cf0b7ba2e50741d0b64cae324eb5de3b1e2f580bbf177e721b67df38488"),
|
|
annotation(t, "PkgType: gemspec"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
FilesAnalyzed: true,
|
|
PackageVerificationCode: &spdx.PackageVerificationCode{
|
|
Value: "c7526b18eaaeb410e82cb0da9288dd02b38ea171",
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("OperatingSystem-20f7fa3049cc748c"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "centos",
|
|
PackageVersion: "8.3.2011",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeOS,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: os-pkgs"),
|
|
annotation(t, "Type: centos"),
|
|
},
|
|
},
|
|
},
|
|
Files: []*spdx.File{
|
|
{
|
|
FileSPDXIdentifier: "File-fa42187221d0d0a8",
|
|
FileName: "tools/project-doe/specifications/actionpack.gemspec",
|
|
Checksums: []spdx.Checksum{
|
|
{
|
|
Algorithm: spdx.SHA1,
|
|
Value: "413f98442c83808042b5d1d2611a346b999bdca5",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
FileSPDXIdentifier: "File-6a540784b0dc6d55",
|
|
FileName: "tools/project-john/specifications/actionpack.gemspec",
|
|
Checksums: []spdx.Checksum{
|
|
{
|
|
Algorithm: spdx.SHA1,
|
|
Value: "d2f9f9aed5161f6e4116a3f9573f41cd832f137c",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "ContainerImage-413bfede37ad01fc"},
|
|
RefB: spdx.DocElementID{ElementRefID: "OperatingSystem-20f7fa3049cc748c"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "ContainerImage-413bfede37ad01fc"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-69f68dd639314edd"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "ContainerImage-413bfede37ad01fc"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-da2cda24d2ecbfe6"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "ContainerImage-413bfede37ad01fc"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "OperatingSystem-20f7fa3049cc748c"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-40c4059fe08523bf"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Package-69f68dd639314edd"},
|
|
RefB: spdx.DocElementID{ElementRefID: "File-fa42187221d0d0a8"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Package-da2cda24d2ecbfe6"},
|
|
RefB: spdx.DocElementID{ElementRefID: "File-6a540784b0dc6d55"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
|
|
OtherLicenses: nil,
|
|
Annotations: nil,
|
|
Reviews: nil,
|
|
},
|
|
},
|
|
{
|
|
name: "happy path for fs scan",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "masahiro331/CVE-2021-41098",
|
|
ArtifactType: artifact.TypeFilesystem,
|
|
Results: types.Results{
|
|
{
|
|
Target: "Gemfile.lock",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.Bundler,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "actioncable",
|
|
Version: "6.1.4.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGem,
|
|
Name: "actioncable",
|
|
Version: "6.1.4.1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Target: "pom.xml",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.Pom,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
ID: "com.example:example:1.0.0",
|
|
Name: "com.example:example",
|
|
Version: "1.0.0",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeMaven,
|
|
Namespace: "com.example",
|
|
Name: "example",
|
|
Version: "1.0.0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "masahiro331/CVE-2021-41098",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/masahiro331/CVE-2021-41098-3ff14136-e09f-4df9-80ea-000000000006",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Application-ed046c4a6b4da30f"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "Gemfile.lock",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: lang-pkgs"),
|
|
annotation(t, "Type: bundler"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Application-800d9e6e0f88ab3a"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "pom.xml",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: lang-pkgs"),
|
|
annotation(t, "Type: pom"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-e78eaf94802a53dc"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "actioncable",
|
|
PackageVersion: "6.1.4.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:gem/actioncable@6.1.4.1",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: Gemfile.lock",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: bundler"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-69cd7625c68537c7"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "com.example:example",
|
|
PackageVersion: "1.0.0",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:maven/com.example/example@1.0.0",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: pom.xml",
|
|
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",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-800d9e6e0f88ab3a"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-69cd7625c68537c7"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-ed046c4a6b4da30f"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-e78eaf94802a53dc"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Filesystem-5af0f1f08c20909a"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Filesystem-5af0f1f08c20909a"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Application-800d9e6e0f88ab3a"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Filesystem-5af0f1f08c20909a"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Application-ed046c4a6b4da30f"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "happy path with various licenses",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "pom.xml",
|
|
ArtifactType: artifact.TypeFilesystem,
|
|
Results: types.Results{
|
|
{
|
|
Target: "pom.xml",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.Pom,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
ID: "com.example:example:1.0.0",
|
|
Name: "com.example:example",
|
|
Version: "1.0.0",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeMaven,
|
|
Namespace: "com.example",
|
|
Name: "example",
|
|
Version: "1.0.0",
|
|
},
|
|
},
|
|
Licenses: []string{
|
|
"text://BSD-4-clause",
|
|
"BSD-4-clause or LGPL-2.0-only",
|
|
"AFL 3.0 with wrong-exceptions",
|
|
"AFL 3.0 with Autoconf-exception-3.0",
|
|
"text://UNKNOWN",
|
|
"UNKNOWN",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "pom.xml",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/pom.xml-3ff14136-e09f-4df9-80ea-000000000004",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Application-800d9e6e0f88ab3a"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "pom.xml",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: lang-pkgs"),
|
|
annotation(t, "Type: pom"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-69cd7625c68537c7"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "com.example:example",
|
|
PackageVersion: "1.0.0",
|
|
PackageLicenseConcluded: "LicenseRef-14b1606fb243e2b6 AND (BSD-4-Clause OR LGPL-2.0-only) AND LicenseRef-77bdf77d8292ce5b AND AFL-3.0 WITH Autoconf-exception-3.0 AND LicenseRef-229659393343e160 AND LicenseRef-a8d01765900624d3",
|
|
PackageLicenseDeclared: "LicenseRef-14b1606fb243e2b6 AND (BSD-4-Clause OR LGPL-2.0-only) AND LicenseRef-77bdf77d8292ce5b AND AFL-3.0 WITH Autoconf-exception-3.0 AND LicenseRef-229659393343e160 AND LicenseRef-a8d01765900624d3",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:maven/com.example/example@1.0.0",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: pom.xml",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgID: com.example:example:1.0.0"),
|
|
annotation(t, "PkgType: pom"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Filesystem-340a6f62df359d6a"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "pom.xml",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-800d9e6e0f88ab3a"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-69cd7625c68537c7"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Filesystem-340a6f62df359d6a"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Filesystem-340a6f62df359d6a"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Application-800d9e6e0f88ab3a"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
OtherLicenses: []*spdx.OtherLicense{
|
|
{
|
|
LicenseIdentifier: "LicenseRef-14b1606fb243e2b6",
|
|
LicenseName: "NOASSERTION",
|
|
ExtractedText: "BSD-4-clause",
|
|
LicenseComment: "The license text represents text found in package metadata and may not represent the full text of the license",
|
|
},
|
|
{
|
|
LicenseIdentifier: "LicenseRef-229659393343e160",
|
|
LicenseName: "NOASSERTION",
|
|
ExtractedText: "UNKNOWN",
|
|
LicenseComment: "The license text represents text found in package metadata and may not represent the full text of the license",
|
|
},
|
|
{
|
|
LicenseIdentifier: "LicenseRef-77bdf77d8292ce5b",
|
|
LicenseName: "AFL-3.0 WITH wrong-exceptions",
|
|
ExtractedText: `This component is licensed under "AFL-3.0 WITH wrong-exceptions"`,
|
|
},
|
|
{
|
|
LicenseIdentifier: "LicenseRef-a8d01765900624d3",
|
|
LicenseName: "UNKNOWN",
|
|
ExtractedText: `This component is licensed under "UNKNOWN"`,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "happy path with vulnerability",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "log4j-core-2.17.0.jar",
|
|
ArtifactType: artifact.TypeFilesystem,
|
|
Results: types.Results{
|
|
{
|
|
Target: "Java",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.Jar,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "org.apache.logging.log4j:log4j-core",
|
|
Version: "2.17.0",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeMaven,
|
|
Namespace: "org.apache.logging.log4j",
|
|
Name: "log4j-core",
|
|
Version: "2.17.0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Vulnerabilities: []types.DetectedVulnerability{
|
|
{
|
|
VulnerabilityID: "CVE-2021-44832",
|
|
PkgName: "org.apache.logging.log4j:log4j-core",
|
|
InstalledVersion: "2.17.0",
|
|
FixedVersion: "2.3.2, 2.12.4, 2.17.1",
|
|
PrimaryURL: "https://avd.aquasec.com/nvd/cve-2021-44832",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "log4j-core-2.17.0.jar",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/log4j-core-2.17.0.jar-3ff14136-e09f-4df9-80ea-000000000003",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-4ee6f197f4811213"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "org.apache.logging.log4j:log4j-core",
|
|
PackageVersion: "2.17.0",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.0",
|
|
},
|
|
{
|
|
Category: "SECURITY",
|
|
RefType: "advisory",
|
|
Locator: "https://avd.aquasec.com/nvd/cve-2021-44832",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: jar"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Filesystem-121e7e7a43f02ab"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "log4j-core-2.17.0.jar",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Filesystem-121e7e7a43f02ab"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Filesystem-121e7e7a43f02ab"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-4ee6f197f4811213"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "happy path aggregate results",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "http://test-aggregate",
|
|
ArtifactType: artifact.TypeRepository,
|
|
Results: types.Results{
|
|
{
|
|
Target: "Node.js",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.NodePkg,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "ruby-typeprof",
|
|
Version: "0.20.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeNPM,
|
|
Name: "ruby-typeprof",
|
|
Version: "0.20.1",
|
|
},
|
|
},
|
|
Licenses: []string{"MIT"},
|
|
Layer: ftypes.Layer{
|
|
DiffID: "sha256:661c3fd3cc16b34c070f3620ca6b03b6adac150f9a7e5d0e3c707a159990f88e",
|
|
},
|
|
Digest: "sha256:a5efa82f08774597165e8c1a102d45d0406913b74c184883ac91f409ae26009d",
|
|
FilePath: "usr/local/lib/ruby/gems/3.1.0/gems/typeprof-0.21.1/vscode/package.json",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "http://test-aggregate",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/repository/test-aggregate-3ff14136-e09f-4df9-80ea-000000000003",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-52b8e939bac2d133"),
|
|
PackageDownloadLocation: "git+http://test-aggregate",
|
|
PackageName: "ruby-typeprof",
|
|
PackageVersion: "0.20.1",
|
|
PackageLicenseConcluded: "MIT",
|
|
PackageLicenseDeclared: "MIT",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:npm/ruby-typeprof@0.20.1",
|
|
},
|
|
},
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "LayerDiffID: sha256:661c3fd3cc16b34c070f3620ca6b03b6adac150f9a7e5d0e3c707a159990f88e"),
|
|
annotation(t, "PkgType: node-pkg"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
FilesAnalyzed: true,
|
|
PackageVerificationCode: &spdx.PackageVerificationCode{
|
|
Value: "da39a3ee5e6b4b0d3255bfef95601890afd80709",
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: "Repository-1a78857c1a6a759e",
|
|
PackageName: "http://test-aggregate",
|
|
PackageDownloadLocation: "git+http://test-aggregate",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Files: []*spdx.File{
|
|
{
|
|
FileName: "usr/local/lib/ruby/gems/3.1.0/gems/typeprof-0.21.1/vscode/package.json",
|
|
FileSPDXIdentifier: "File-a52825a3e5bc6dfe",
|
|
Checksums: []common.Checksum{
|
|
{
|
|
Algorithm: common.SHA256,
|
|
Value: "a5efa82f08774597165e8c1a102d45d0406913b74c184883ac91f409ae26009d",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Repository-1a78857c1a6a759e"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Package-52b8e939bac2d133"},
|
|
RefB: spdx.DocElementID{ElementRefID: "File-a52825a3e5bc6dfe"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Repository-1a78857c1a6a759e"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-52b8e939bac2d133"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "happy path empty",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "empty/path",
|
|
ArtifactType: artifact.TypeFilesystem,
|
|
Results: types.Results{},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "empty/path",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/empty/path-3ff14136-e09f-4df9-80ea-000000000002",
|
|
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageName: "empty/path",
|
|
PackageSPDXIdentifier: "Filesystem-70f34983067dba86",
|
|
PackageDownloadLocation: "NONE",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Filesystem-70f34983067dba86"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "happy path secret",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "secret",
|
|
ArtifactType: artifact.TypeFilesystem,
|
|
Results: types.Results{
|
|
{
|
|
Target: "key.pem",
|
|
Class: types.ClassSecret,
|
|
Secrets: []types.DetectedSecret{
|
|
{
|
|
RuleID: "private-key",
|
|
Category: "AsymmetricPrivateKey",
|
|
Severity: "HIGH",
|
|
Title: "Asymmetric Private Key",
|
|
StartLine: 1,
|
|
EndLine: 1,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "secret",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/secret-3ff14136-e09f-4df9-80ea-000000000002",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageName: "secret",
|
|
PackageSPDXIdentifier: "Filesystem-5c08d34162a2c5d3",
|
|
PackageDownloadLocation: "NONE",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Filesystem-5c08d34162a2c5d3"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "go library local",
|
|
inputReport: types.Report{
|
|
SchemaVersion: report.SchemaVersion,
|
|
ArtifactName: "go-artifact",
|
|
ArtifactType: artifact.TypeFilesystem,
|
|
Results: types.Results{
|
|
{
|
|
Target: "/usr/local/bin/test",
|
|
Class: types.ClassLangPkg,
|
|
Type: ftypes.GoBinary,
|
|
Packages: []ftypes.Package{
|
|
{
|
|
Name: "./private_repos/cnrm.googlesource.com/cnrm/",
|
|
Version: "",
|
|
},
|
|
{
|
|
Name: "golang.org/x/crypto",
|
|
Version: "v0.0.1",
|
|
Identifier: ftypes.PkgIdentifier{
|
|
UID: "161541A259EF014B",
|
|
PURL: &packageurl.PackageURL{
|
|
Type: packageurl.TypeGolang,
|
|
Namespace: "golang.org/x",
|
|
Name: "crypto",
|
|
Version: "v0.0.1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantSBOM: &spdx.Document{
|
|
SPDXVersion: spdx.Version,
|
|
DataLicense: spdx.DataLicense,
|
|
SPDXIdentifier: "DOCUMENT",
|
|
DocumentName: "go-artifact",
|
|
DocumentNamespace: "http://aquasecurity.github.io/trivy/filesystem/go-artifact-3ff14136-e09f-4df9-80ea-000000000005",
|
|
CreationInfo: &spdx.CreationInfo{
|
|
Creators: []common.Creator{
|
|
{
|
|
Creator: "aquasecurity",
|
|
CreatorType: "Organization",
|
|
},
|
|
{
|
|
Creator: "trivy-0.56.2",
|
|
CreatorType: "Tool",
|
|
},
|
|
},
|
|
Created: "2021-08-25T12:20:30Z",
|
|
},
|
|
Packages: []*spdx.Package{
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Application-aab0f4e8cf174c67"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "/usr/local/bin/test",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeApplication,
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "Class: lang-pkgs"),
|
|
annotation(t, "Type: gobinary"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-b1c3b9e2363f5ff7"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "./private_repos/cnrm.googlesource.com/cnrm/",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: /usr/local/bin/test",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: gobinary"),
|
|
},
|
|
},
|
|
{
|
|
PackageSPDXIdentifier: spdx.ElementID("Package-b9b7ae633941e083"),
|
|
PackageDownloadLocation: "NONE",
|
|
PackageName: "golang.org/x/crypto",
|
|
PackageVersion: "v0.0.1",
|
|
PackageLicenseConcluded: "NOASSERTION",
|
|
PackageLicenseDeclared: "NOASSERTION",
|
|
PackageExternalReferences: []*spdx.PackageExternalReference{
|
|
{
|
|
Category: tspdx.CategoryPackageManager,
|
|
RefType: tspdx.RefTypePurl,
|
|
Locator: "pkg:golang/golang.org/x/crypto@v0.0.1",
|
|
},
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeLibrary,
|
|
PackageSupplier: &spdx.Supplier{Supplier: tspdx.PackageSupplierNoAssertion},
|
|
PackageSourceInfo: "package found in: /usr/local/bin/test",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "PkgType: gobinary"),
|
|
},
|
|
},
|
|
{
|
|
PackageName: "go-artifact",
|
|
PackageSPDXIdentifier: "Filesystem-e340f27468b382be",
|
|
PackageDownloadLocation: "NONE",
|
|
Annotations: []spdx.Annotation{
|
|
annotation(t, "SchemaVersion: 2"),
|
|
},
|
|
PrimaryPackagePurpose: tspdx.PackagePurposeSource,
|
|
},
|
|
},
|
|
Relationships: []*spdx.Relationship{
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-aab0f4e8cf174c67"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-b1c3b9e2363f5ff7"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Application-aab0f4e8cf174c67"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Package-b9b7ae633941e083"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "DOCUMENT"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Filesystem-e340f27468b382be"},
|
|
Relationship: "DESCRIBES",
|
|
},
|
|
{
|
|
RefA: spdx.DocElementID{ElementRefID: "Filesystem-e340f27468b382be"},
|
|
RefB: spdx.DocElementID{ElementRefID: "Application-aab0f4e8cf174c67"},
|
|
Relationship: "CONTAINS",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
// Fake function calculating the hash value
|
|
h := fnv.New64()
|
|
hasher := func(v any, format hashstructure.Format, opts *hashstructure.HashOptions) (uint64, error) {
|
|
h.Reset()
|
|
|
|
var str string
|
|
switch vv := v.(type) {
|
|
case *core.Component:
|
|
str = vv.Name + vv.Version + vv.SrcFile
|
|
for _, f := range vv.Files {
|
|
str += f.Path
|
|
}
|
|
case spdx.OtherLicense:
|
|
str = vv.ExtractedText + vv.LicenseName
|
|
case string:
|
|
str = vv
|
|
default:
|
|
require.Failf(t, "unknown type", "%T", v)
|
|
}
|
|
|
|
if _, err := h.Write([]byte(str)); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return h.Sum64(), nil
|
|
}
|
|
|
|
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.56.2", tspdx.WithHasher(hasher))
|
|
spdxDoc, err := marshaler.MarshalReport(ctx, tc.inputReport)
|
|
require.NoError(t, err)
|
|
|
|
assert.NoError(t, spdxlib.ValidateDocument(spdxDoc))
|
|
assert.Equal(t, tc.wantSBOM, spdxDoc)
|
|
})
|
|
}
|
|
}
|