mirror of
https://github.com/anchore/syft
synced 2024-11-10 14:24:12 +00:00
Add go binary h1 digest to SPDX (#1265)
This commit is contained in:
parent
6e764815d0
commit
78a0af2e2d
8 changed files with 468 additions and 36 deletions
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/formats/common/util"
|
||||
"github.com/anchore/syft/syft/linux"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
|
@ -293,6 +294,7 @@ func toSyftPackage(p *spdx.Package2_2) *pkg.Package {
|
|||
return &sP
|
||||
}
|
||||
|
||||
//nolint:funlen
|
||||
func extractMetadata(p *spdx.Package2_2, info pkgInfo) (pkg.MetadataType, interface{}) {
|
||||
arch := info.qualifierValue(pkg.PURLQualifierArch)
|
||||
upstreamValue := info.qualifierValue(pkg.PURLQualifierUpstream)
|
||||
|
@ -352,6 +354,20 @@ func extractMetadata(p *spdx.Package2_2, info pkgInfo) (pkg.MetadataType, interf
|
|||
return pkg.JavaMetadataType, pkg.JavaMetadata{
|
||||
ArchiveDigests: digests,
|
||||
}
|
||||
case pkg.GoModulePkg:
|
||||
var h1Digest string
|
||||
for _, value := range p.PackageChecksums {
|
||||
digest, err := util.HDigestFromSHA(string(value.Algorithm), value.Value)
|
||||
if err != nil {
|
||||
log.Debugf("invalid h1digest: %v %v", value, err)
|
||||
continue
|
||||
}
|
||||
h1Digest = digest
|
||||
break
|
||||
}
|
||||
return pkg.GolangBinMetadataType, pkg.GolangBinMetadata{
|
||||
H1Digest: h1Digest,
|
||||
}
|
||||
}
|
||||
return pkg.UnknownMetadataType, nil
|
||||
}
|
||||
|
|
|
@ -234,3 +234,84 @@ func TestExtractSourceFromNamespaces(t *testing.T) {
|
|||
require.Equal(t, tt.expected, extractSchemeFromNamespace(tt.namespace))
|
||||
}
|
||||
}
|
||||
|
||||
func TestH1Digest(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pkg spdx.Package2_2
|
||||
expectedDigest string
|
||||
}{
|
||||
{
|
||||
name: "valid h1digest",
|
||||
pkg: spdx.Package2_2{
|
||||
PackageName: "github.com/googleapis/gnostic",
|
||||
PackageVersion: "v0.5.5",
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference2_2{
|
||||
{
|
||||
Category: "PACKAGE_MANAGER",
|
||||
Locator: "pkg:golang/github.com/googleapis/gnostic@v0.5.5",
|
||||
RefType: "purl",
|
||||
},
|
||||
},
|
||||
PackageChecksums: map[spdx.ChecksumAlgorithm]spdx.Checksum{
|
||||
spdx.SHA256: {
|
||||
Algorithm: spdx.SHA256,
|
||||
Value: "f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDigest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||
},
|
||||
{
|
||||
name: "invalid h1digest algorithm",
|
||||
pkg: spdx.Package2_2{
|
||||
PackageName: "github.com/googleapis/gnostic",
|
||||
PackageVersion: "v0.5.5",
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference2_2{
|
||||
{
|
||||
Category: "PACKAGE_MANAGER",
|
||||
Locator: "pkg:golang/github.com/googleapis/gnostic@v0.5.5",
|
||||
RefType: "purl",
|
||||
},
|
||||
},
|
||||
PackageChecksums: map[spdx.ChecksumAlgorithm]spdx.Checksum{
|
||||
spdx.SHA256: {
|
||||
Algorithm: spdx.SHA1,
|
||||
Value: "f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDigest: "",
|
||||
},
|
||||
{
|
||||
name: "invalid h1digest digest",
|
||||
pkg: spdx.Package2_2{
|
||||
PackageName: "github.com/googleapis/gnostic",
|
||||
PackageVersion: "v0.5.5",
|
||||
PackageExternalReferences: []*spdx.PackageExternalReference2_2{
|
||||
{
|
||||
Category: "PACKAGE_MANAGER",
|
||||
Locator: "pkg:golang/github.com/googleapis/gnostic@v0.5.5",
|
||||
RefType: "purl",
|
||||
},
|
||||
},
|
||||
PackageChecksums: map[spdx.ChecksumAlgorithm]spdx.Checksum{
|
||||
spdx.SHA256: {
|
||||
Algorithm: spdx.SHA256,
|
||||
Value: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedDigest: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
p := toSyftPackage(&test.pkg)
|
||||
require.Equal(t, pkg.GolangBinMetadataType, p.MetadataType)
|
||||
meta := p.Metadata.(pkg.GolangBinMetadata)
|
||||
require.Equal(t, test.expectedDigest, meta.H1Digest)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
57
syft/formats/common/util/h_digest.go
Normal file
57
syft/formats/common/util/h_digest.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HDigestToSHA converts a h# digest, such as h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= to an
|
||||
// algorithm such as sha256 and a hex encoded digest
|
||||
func HDigestToSHA(digest string) (string, string, error) {
|
||||
// hash is base64, but we need hex encode
|
||||
parts := strings.Split(digest, ":")
|
||||
if len(parts) == 2 {
|
||||
algo := parts[0]
|
||||
hash := parts[1]
|
||||
checksum, err := base64.StdEncoding.DecodeString(hash)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
hexStr := hex.EncodeToString(checksum)
|
||||
|
||||
switch algo {
|
||||
// golang h1 hash == sha256
|
||||
case "h1":
|
||||
algo = "sha256"
|
||||
default:
|
||||
return "", "", fmt.Errorf("unsupported h#digest algorithm: %s", algo)
|
||||
}
|
||||
|
||||
return algo, hexStr, nil
|
||||
}
|
||||
|
||||
return "", "", fmt.Errorf("invalid h#digest: %s", digest)
|
||||
}
|
||||
|
||||
// HDigestFromSHA converts an algorithm, such sha256 with a hex encoded digest to a
|
||||
// h# value such as h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
func HDigestFromSHA(algorithm string, digest string) (string, error) {
|
||||
if digest == "" {
|
||||
return "", fmt.Errorf("no digest value provided")
|
||||
}
|
||||
// digest is hex, but we need to base64 encode
|
||||
algorithm = strings.ToLower(algorithm)
|
||||
if algorithm == "sha256" {
|
||||
checksum, err := hex.DecodeString(digest)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// hash is hex, but we need base64
|
||||
b64digest := base64.StdEncoding.EncodeToString(checksum)
|
||||
return fmt.Sprintf("h1:%s", b64digest), nil
|
||||
}
|
||||
return "", fmt.Errorf("not a recognized h#digest algorithm: %s", algorithm)
|
||||
}
|
107
syft/formats/common/util/h_digest_test.go
Normal file
107
syft/formats/common/util/h_digest_test.go
Normal file
|
@ -0,0 +1,107 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_HDigestToSHA(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
hDigest string
|
||||
expected string
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
name: "valid h1digest",
|
||||
hDigest: "h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=",
|
||||
expected: "sha256:f10a9c0e0ceb52a9546ff1b63d04d68ae786a33b91d7cf3881d74ccb093a88b5",
|
||||
error: false,
|
||||
},
|
||||
{
|
||||
name: "other valid h1digest",
|
||||
hDigest: "h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=",
|
||||
expected: "sha256:4933fc0ef0f273f748e5bf13e61b21b648d2f84e364e7cac34250f7637221a16",
|
||||
error: false,
|
||||
},
|
||||
{
|
||||
name: "invalid h1digest",
|
||||
hDigest: "h12:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=",
|
||||
expected: "",
|
||||
error: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
algo, digest, err := HDigestToSHA(test.hDigest)
|
||||
if test.error {
|
||||
require.Error(t, err)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
got := fmt.Sprintf("%s:%s", algo, digest)
|
||||
require.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_HDigestFromSHA(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sha string
|
||||
expected string
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
name: "valid sha",
|
||||
sha: "sha256:f10a9c0e0ceb52a9546ff1b63d04d68ae786a33b91d7cf3881d74ccb093a88b5",
|
||||
expected: "h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=",
|
||||
error: false,
|
||||
},
|
||||
{
|
||||
name: "other valid sha",
|
||||
sha: "sha256:4933fc0ef0f273f748e5bf13e61b21b648d2f84e364e7cac34250f7637221a16",
|
||||
expected: "h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=",
|
||||
error: false,
|
||||
},
|
||||
{
|
||||
name: "invalid sha",
|
||||
expected: "h12:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=",
|
||||
sha: "sha256:f10a9c0e0zzzzceb52a99968ae786a33b91d7cf3881d74ccb093a88b5",
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
name: "invalid algorithm",
|
||||
expected: "h12:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=",
|
||||
sha: "sha1:f10a9c0e0ceb52a9546ff1b63d04d68ae786a33b91d7cf3881d74ccb093a88b5",
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
name: "empty sha",
|
||||
expected: "",
|
||||
sha: "sha256:",
|
||||
error: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
parts := strings.Split(test.sha, ":")
|
||||
algo := parts[0]
|
||||
digest := parts[1]
|
||||
got, err := HDigestFromSHA(algo, digest)
|
||||
if test.error {
|
||||
require.Error(t, err)
|
||||
return
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/formats/common/spdxhelpers"
|
||||
"github.com/anchore/syft/syft/formats/common/util"
|
||||
"github.com/anchore/syft/syft/formats/spdx22json/model"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
|
@ -53,24 +54,8 @@ func toPackages(catalog *pkg.Catalog, relationships []artifact.Relationship) []m
|
|||
for _, p := range catalog.Sorted() {
|
||||
license := spdxhelpers.License(p)
|
||||
packageSpdxID := model.ElementID(p.ID()).String()
|
||||
filesAnalyzed := false
|
||||
checksums, filesAnalyzed := toPackageChecksums(p)
|
||||
|
||||
// we generate digest for some Java packages
|
||||
// see page 33 of the spdx specification for 2.2
|
||||
// spdx.github.io/spdx-spec/package-information/#710-package-checksum-field
|
||||
var checksums []model.Checksum
|
||||
if p.MetadataType == pkg.JavaMetadataType {
|
||||
javaMetadata := p.Metadata.(pkg.JavaMetadata)
|
||||
if len(javaMetadata.ArchiveDigests) > 0 {
|
||||
filesAnalyzed = true
|
||||
for _, digest := range javaMetadata.ArchiveDigests {
|
||||
checksums = append(checksums, model.Checksum{
|
||||
Algorithm: strings.ToUpper(digest.Algorithm),
|
||||
ChecksumValue: digest.Value,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// note: the license concluded and declared should be the same since we are collecting license information
|
||||
// from the project data itself (the installed package files).
|
||||
packages = append(packages, model.Package{
|
||||
|
@ -100,6 +85,38 @@ func toPackages(catalog *pkg.Catalog, relationships []artifact.Relationship) []m
|
|||
return packages
|
||||
}
|
||||
|
||||
func toPackageChecksums(p pkg.Package) ([]model.Checksum, bool) {
|
||||
filesAnalyzed := false
|
||||
var checksums []model.Checksum
|
||||
switch meta := p.Metadata.(type) {
|
||||
// we generate digest for some Java packages
|
||||
// see page 33 of the spdx specification for 2.2
|
||||
// spdx.github.io/spdx-spec/package-information/#710-package-checksum-field
|
||||
case pkg.JavaMetadata:
|
||||
if len(meta.ArchiveDigests) > 0 {
|
||||
filesAnalyzed = true
|
||||
for _, digest := range meta.ArchiveDigests {
|
||||
checksums = append(checksums, model.Checksum{
|
||||
Algorithm: strings.ToUpper(digest.Algorithm),
|
||||
ChecksumValue: digest.Value,
|
||||
})
|
||||
}
|
||||
}
|
||||
case pkg.GolangBinMetadata:
|
||||
algo, hexStr, err := util.HDigestToSHA(meta.H1Digest)
|
||||
if err != nil {
|
||||
log.Debugf("invalid h1digest: %s: %v", meta.H1Digest, err)
|
||||
break
|
||||
}
|
||||
algo = strings.ToUpper(algo)
|
||||
checksums = append(checksums, model.Checksum{
|
||||
Algorithm: strings.ToUpper(algo),
|
||||
ChecksumValue: hexStr,
|
||||
})
|
||||
}
|
||||
return checksums, filesAnalyzed
|
||||
}
|
||||
|
||||
func fileIDsForPackage(packageSpdxID string, relationships []artifact.Relationship) (fileIDs []string) {
|
||||
for _, relationship := range relationships {
|
||||
if relationship.Type != artifact.ContainsRelationship {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package spdx22json
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
|
@ -253,3 +255,64 @@ func Test_fileIDsForPackage(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_H1Digest(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pkg pkg.Package
|
||||
expectedDigest string
|
||||
}{
|
||||
{
|
||||
name: "valid h1digest",
|
||||
pkg: pkg.Package{
|
||||
Name: "github.com/googleapis/gnostic",
|
||||
Version: "v0.5.5",
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
H1Digest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||
},
|
||||
},
|
||||
expectedDigest: "SHA256:f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
|
||||
},
|
||||
{
|
||||
name: "invalid h1digest",
|
||||
pkg: pkg.Package{
|
||||
Name: "github.com/googleapis/gnostic",
|
||||
Version: "v0.5.5",
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
H1Digest: "h1:9fHAtK0uzzz",
|
||||
},
|
||||
},
|
||||
expectedDigest: "",
|
||||
},
|
||||
{
|
||||
name: "unsupported h-digest",
|
||||
pkg: pkg.Package{
|
||||
Name: "github.com/googleapis/gnostic",
|
||||
Version: "v0.5.5",
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
H1Digest: "h12:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||
},
|
||||
},
|
||||
expectedDigest: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
catalog := pkg.NewCatalog(test.pkg)
|
||||
pkgs := toPackages(catalog, nil)
|
||||
require.Len(t, pkgs, 1)
|
||||
p := pkgs[0]
|
||||
if test.expectedDigest == "" {
|
||||
require.Len(t, p.Checksums, 0)
|
||||
} else {
|
||||
require.Len(t, p.Checksums, 1)
|
||||
c := p.Checksums[0]
|
||||
require.Equal(t, test.expectedDigest, fmt.Sprintf("%s:%s", c.Algorithm, c.ChecksumValue))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,16 @@ package spdx22tagvalue
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spdx/tools-golang/spdx"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/spdxlicense"
|
||||
"github.com/anchore/syft/syft/formats/common/spdxhelpers"
|
||||
"github.com/anchore/syft/syft/formats/common/util"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
)
|
||||
|
@ -101,24 +104,7 @@ func toFormatPackages(catalog *pkg.Catalog) map[spdx.ElementID]*spdx.Package2_2
|
|||
// in the Comments on License field (section 3.16). With respect to NOASSERTION, a written explanation in
|
||||
// the Comments on License field (section 3.16) is preferred.
|
||||
license := spdxhelpers.License(p)
|
||||
|
||||
filesAnalyzed := false
|
||||
checksums := make(map[spdx.ChecksumAlgorithm]spdx.Checksum)
|
||||
|
||||
// If the pkg type is Java we have attempted to generated a digest
|
||||
// FilesAnalyzed should be true in this case
|
||||
if p.MetadataType == pkg.JavaMetadataType {
|
||||
javaMetadata := p.Metadata.(pkg.JavaMetadata)
|
||||
if len(javaMetadata.ArchiveDigests) > 0 {
|
||||
filesAnalyzed = true
|
||||
for _, digest := range javaMetadata.ArchiveDigests {
|
||||
checksums[spdx.ChecksumAlgorithm(digest.Algorithm)] = spdx.Checksum{
|
||||
Algorithm: spdx.ChecksumAlgorithm(digest.Algorithm),
|
||||
Value: digest.Value,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checksums, filesAnalyzed := toPackageChecksums(p)
|
||||
|
||||
results[spdx.ElementID(id)] = &spdx.Package2_2{
|
||||
|
||||
|
@ -181,7 +167,7 @@ func toFormatPackages(catalog *pkg.Catalog) map[spdx.ElementID]*spdx.Package2_2
|
|||
IsFilesAnalyzedTagPresent: true,
|
||||
|
||||
// 3.9: Package Verification Code
|
||||
// Cardinality: mandatory, one if filesAnalyzed is true / omitted;
|
||||
// Cardinality: optional, one if filesAnalyzed is true / omitted;
|
||||
// zero (must be omitted) if filesAnalyzed is false
|
||||
PackageVerificationCode: "",
|
||||
// Spec also allows specifying a single file to exclude from the
|
||||
|
@ -280,6 +266,38 @@ func toFormatPackages(catalog *pkg.Catalog) map[spdx.ElementID]*spdx.Package2_2
|
|||
return results
|
||||
}
|
||||
|
||||
func toPackageChecksums(p pkg.Package) (map[spdx.ChecksumAlgorithm]spdx.Checksum, bool) {
|
||||
filesAnalyzed := false
|
||||
checksums := map[spdx.ChecksumAlgorithm]spdx.Checksum{}
|
||||
switch meta := p.Metadata.(type) {
|
||||
// we generate digest for some Java packages
|
||||
// see page 33 of the spdx specification for 2.2
|
||||
// spdx.github.io/spdx-spec/package-information/#710-package-checksum-field
|
||||
case pkg.JavaMetadata:
|
||||
if len(meta.ArchiveDigests) > 0 {
|
||||
filesAnalyzed = true
|
||||
for _, digest := range meta.ArchiveDigests {
|
||||
checksums[spdx.ChecksumAlgorithm(digest.Algorithm)] = spdx.Checksum{
|
||||
Algorithm: spdx.ChecksumAlgorithm(digest.Algorithm),
|
||||
Value: digest.Value,
|
||||
}
|
||||
}
|
||||
}
|
||||
case pkg.GolangBinMetadata:
|
||||
algo, hexStr, err := util.HDigestToSHA(meta.H1Digest)
|
||||
if err != nil {
|
||||
log.Debugf("invalid h1digest: %s: %v", meta.H1Digest, err)
|
||||
break
|
||||
}
|
||||
algo = strings.ToUpper(algo)
|
||||
checksums[spdx.ChecksumAlgorithm(algo)] = spdx.Checksum{
|
||||
Algorithm: spdx.ChecksumAlgorithm(algo),
|
||||
Value: hexStr,
|
||||
}
|
||||
}
|
||||
return checksums, filesAnalyzed
|
||||
}
|
||||
|
||||
func formatSPDXExternalRefs(p pkg.Package) (refs []*spdx.PackageExternalReference2_2) {
|
||||
for _, ref := range spdxhelpers.ExternalRefs(p) {
|
||||
refs = append(refs, &spdx.PackageExternalReference2_2{
|
||||
|
|
73
syft/formats/spdx22tagvalue/to_format_model_test.go
Normal file
73
syft/formats/spdx22tagvalue/to_format_model_test.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
package spdx22tagvalue
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func Test_H1Digest(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pkg pkg.Package
|
||||
expectedDigest string
|
||||
}{
|
||||
{
|
||||
name: "valid h1digest",
|
||||
pkg: pkg.Package{
|
||||
Name: "github.com/googleapis/gnostic",
|
||||
Version: "v0.5.5",
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
H1Digest: "h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||
},
|
||||
},
|
||||
expectedDigest: "SHA256:f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
|
||||
},
|
||||
{
|
||||
name: "invalid h1digest",
|
||||
pkg: pkg.Package{
|
||||
Name: "github.com/googleapis/gnostic",
|
||||
Version: "v0.5.5",
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
H1Digest: "h1:9fHAtK0uzzz",
|
||||
},
|
||||
},
|
||||
expectedDigest: "",
|
||||
},
|
||||
{
|
||||
name: "unsupported h-digest",
|
||||
pkg: pkg.Package{
|
||||
Name: "github.com/googleapis/gnostic",
|
||||
Version: "v0.5.5",
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
H1Digest: "h12:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=",
|
||||
},
|
||||
},
|
||||
expectedDigest: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
catalog := pkg.NewCatalog(test.pkg)
|
||||
pkgs := toFormatPackages(catalog)
|
||||
require.Len(t, pkgs, 1)
|
||||
for _, p := range pkgs {
|
||||
if test.expectedDigest == "" {
|
||||
require.Len(t, p.PackageChecksums, 0)
|
||||
} else {
|
||||
require.Len(t, p.PackageChecksums, 1)
|
||||
for _, c := range p.PackageChecksums {
|
||||
require.Equal(t, test.expectedDigest, fmt.Sprintf("%s:%s", c.Algorithm, c.Value))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue