Merge "Update generateSPDXNamespace to generate a unique spdx doc namespace" am: fad3925959 am: db5ae5b97a

Original change: https://android-review.googlesource.com/c/platform/build/+/2540830

Change-Id: Ie874d0a5c9332c69e5c5696ff0b802cd7225b680
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot 2023-04-21 17:58:11 +00:00 committed by Automerger Merge Worker
commit 8b4d141c5a
2 changed files with 132 additions and 33 deletions

View file

@ -55,6 +55,7 @@ type context struct {
product string
stripPrefix []string
creationTime creationTimeGetter
buildid string
}
func (ctx context) strip(installPath string) string {
@ -124,6 +125,7 @@ Options:
depsFile := flags.String("d", "", "Where to write the deps file")
product := flags.String("product", "", "The name of the product for which the notice is generated.")
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
buildid := flags.String("build_id", "", "Uniquely identifies the build. (default timestamp)")
flags.Parse(expandedArgs)
@ -162,7 +164,7 @@ Options:
ofile = obuf
}
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, actualTime}
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, actualTime, *buildid}
spdxDoc, deps, err := sbomGenerator(ctx, flags.Args()...)
@ -317,14 +319,21 @@ func inputFiles(lg *compliance.LicenseGraph, pmix *projectmetadata.Index, licens
}
// generateSPDXNamespace generates a unique SPDX Document Namespace using a SHA1 checksum
// and the CreationInfo.Created field as the date.
func generateSPDXNamespace(created string) string {
// Compute a SHA1 checksum of the CreationInfo.Created field.
hash := sha1.Sum([]byte(created))
checksum := hex.EncodeToString(hash[:])
func generateSPDXNamespace(buildid string, created string, files ...string) string {
// Combine the checksum and timestamp to generate the SPDX Namespace.
namespace := fmt.Sprintf("SPDXRef-DOCUMENT-%s-%s", created, checksum)
seed := strings.Join(files, "")
if buildid == "" {
seed += created
} else {
seed += buildid
}
// Compute a SHA1 checksum of the seed.
hash := sha1.Sum([]byte(seed))
uuid := hex.EncodeToString(hash[:])
namespace := fmt.Sprintf("SPDXRef-DOCUMENT-%s", uuid)
return namespace
}
@ -523,7 +532,7 @@ func sbomGenerator(ctx *context, files ...string) (*spdx.Document, []string, err
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: docName,
DocumentNamespace: generateSPDXNamespace(ci.Created),
DocumentNamespace: generateSPDXNamespace(ctx.buildid, ci.Created, files...),
CreationInfo: ci,
Packages: pkgs,
Relationships: relationships,

View file

@ -59,7 +59,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-firstparty-highest.apex",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/highest.apex.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -187,7 +187,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-firstparty-application",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/application.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -266,7 +266,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-firstparty-container.zip",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/container.zip.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -394,7 +394,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-firstparty-bin-bin1",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/bin/bin1.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -460,7 +460,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-firstparty-lib-libd.so",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/firstparty/lib/libd.so.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -500,7 +500,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-notice-highest.apex",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/highest.apex.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -634,7 +634,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-notice-container.zip",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/container.zip.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -768,7 +768,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-notice-application",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/application.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -853,7 +853,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-notice-bin-bin1",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/bin/bin1.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -925,7 +925,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-notice-lib-libd.so",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/notice/lib/libd.so.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -965,7 +965,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-reciprocal-highest.apex",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/highest.apex.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1105,7 +1105,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-reciprocal-application",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/application.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1196,7 +1196,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-reciprocal-bin-bin1",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/bin/bin1.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1268,7 +1268,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-reciprocal-lib-libd.so",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/reciprocal/lib/libd.so.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1308,7 +1308,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-restricted-highest.apex",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/highest.apex.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1454,7 +1454,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-restricted-container.zip",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/container.zip.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1600,7 +1600,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-restricted-bin-bin1",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/bin/bin1.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1678,7 +1678,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-restricted-lib-libd.so",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/restricted/lib/libd.so.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1718,7 +1718,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-proprietary-highest.apex",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/highest.apex.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -1864,7 +1864,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-proprietary-container.zip",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/container.zip.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -2010,7 +2010,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-proprietary-application",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/application.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -2101,7 +2101,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-proprietary-bin-bin1",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/bin/bin1.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -2173,7 +2173,7 @@ func Test(t *testing.T) {
DataLicense: "CC0-1.0",
SPDXIdentifier: "DOCUMENT",
DocumentName: "testdata-proprietary-lib-libd.so",
DocumentNamespace: generateSPDXNamespace("1970-01-01T00:00:00Z"),
DocumentNamespace: generateSPDXNamespace("", "1970-01-01T00:00:00Z", "testdata/proprietary/lib/libd.so.meta_lic"),
CreationInfo: getCreationInfo(t),
Packages: []*spdx.Package{
{
@ -2215,7 +2215,7 @@ func Test(t *testing.T) {
rootFiles = append(rootFiles, "testdata/"+tt.condition+"/"+r)
}
ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "", []string{tt.stripPrefix}, fakeTime}
ctx := context{stdout, stderr, compliance.GetFS(tt.outDir), "", []string{tt.stripPrefix}, fakeTime, ""}
spdxDoc, deps, err := sbomGenerator(&ctx, rootFiles...)
if err != nil {
@ -2262,6 +2262,96 @@ func Test(t *testing.T) {
}
}
func TestGenerateSPDXNamespace(t *testing.T) {
buildID1 := "example-1"
buildID2 := "example-2"
files1 := "file1"
timestamp1 := "2022-05-01"
timestamp2 := "2022-05-02"
files2 := "file2"
// Test case 1: different timestamps, same files
nsh1 := generateSPDXNamespace("", timestamp1, files1)
nsh2 := generateSPDXNamespace("", timestamp2, files1)
if nsh1 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp1, files1)
}
if nsh2 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp2, files1)
}
if nsh1 == nsh2 {
t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", "", timestamp1, files1, "", timestamp2, files1)
}
// Test case 2: different build ids, same timestamps and files
nsh1 = generateSPDXNamespace(buildID1, timestamp1, files1)
nsh2 = generateSPDXNamespace(buildID2, timestamp1, files1)
if nsh1 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files1)
}
if nsh2 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID2, timestamp1, files1)
}
if nsh1 == nsh2 {
t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", buildID1, timestamp1, files1, buildID2, timestamp1, files1)
}
// Test case 3: same build ids and files, different timestamps
nsh1 = generateSPDXNamespace(buildID1, timestamp1, files1)
nsh2 = generateSPDXNamespace(buildID1, timestamp2, files1)
if nsh1 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files1)
}
if nsh2 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp2, files1)
}
if nsh1 != nsh2 {
t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected same namespace hashes, but got different: %s and %s", buildID1, timestamp1, files1, buildID2, timestamp1, files1, nsh1, nsh2)
}
// Test case 4: same build ids and timestamps, different files
nsh1 = generateSPDXNamespace(buildID1, timestamp1, files1)
nsh2 = generateSPDXNamespace(buildID1, timestamp1, files2)
if nsh1 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files1)
}
if nsh2 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", buildID1, timestamp1, files2)
}
if nsh1 == nsh2 {
t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", buildID1, timestamp1, files1, buildID1, timestamp1, files2)
}
// Test case 5: empty build ids, same timestamps and different files
nsh1 = generateSPDXNamespace("", timestamp1, files1)
nsh2 = generateSPDXNamespace("", timestamp1, files2)
if nsh1 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp1, files1)
}
if nsh2 == "" {
t.Errorf("generateSPDXNamespace(%s, %s, %s): expected non-empty string, but got empty string", "", timestamp1, files2)
}
if nsh1 == nsh2 {
t.Errorf("generateSPDXNamespace(%s, %s, %s) and generateSPDXNamespace(%s, %s, %s): expected different namespace hashes, but got the same", "", timestamp1, files1, "", timestamp1, files2)
}
}
func getCreationInfo(t *testing.T) *spdx.CreationInfo {
ci, err := builder2v2.BuildCreationInfoSection2_2("Organization", "Google LLC", nil)
if err != nil {