xref: /aosp_15_r20/external/spdx-tools/utils/verification.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1// Package utils contains various utility functions to support the
2// main tools-golang packages.
3// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
4package utils
5
6import (
7	"crypto/sha1"
8	"fmt"
9	"sort"
10	"strings"
11
12	"github.com/spdx/tools-golang/spdx/common"
13	"github.com/spdx/tools-golang/spdx/v2_1"
14	"github.com/spdx/tools-golang/spdx/v2_2"
15	"github.com/spdx/tools-golang/spdx/v2_3"
16)
17
18// GetVerificationCode2_1 takes a slice of files and an optional filename
19// for an "excludes" file, and returns a Package Verification Code calculated
20// according to SPDX spec version 2.1, section 3.9.4.
21func GetVerificationCode2_1(files []*v2_1.File, excludeFile string) (common.PackageVerificationCode, error) {
22	// create slice of strings - unsorted SHA1s for all files
23	shas := []string{}
24	for i, f := range files {
25		if f == nil {
26			return common.PackageVerificationCode{}, fmt.Errorf("got nil file for identifier %v", i)
27		}
28		if f.FileName != excludeFile {
29			// find the SHA1 hash, if present
30			for _, checksum := range f.Checksums {
31				if checksum.Algorithm == common.SHA1 {
32					shas = append(shas, checksum.Value)
33				}
34			}
35		}
36	}
37
38	// sort the strings
39	sort.Strings(shas)
40
41	// concatenate them into one string, with no trailing separators
42	shasConcat := strings.Join(shas, "")
43
44	// and get its SHA1 value
45	hsha1 := sha1.New()
46	hsha1.Write([]byte(shasConcat))
47	bs := hsha1.Sum(nil)
48
49	code := common.PackageVerificationCode{
50		Value:         fmt.Sprintf("%x", bs),
51		ExcludedFiles: []string{excludeFile},
52	}
53
54	return code, nil
55}
56
57// GetVerificationCode2_2 takes a slice of files and an optional filename
58// for an "excludes" file, and returns a Package Verification Code calculated
59// according to SPDX spec version 2.2, section 3.9.4.
60func GetVerificationCode2_2(files []*v2_2.File, excludeFile string) (common.PackageVerificationCode, error) {
61	// create slice of strings - unsorted SHA1s for all files
62	shas := []string{}
63	for i, f := range files {
64		if f == nil {
65			return common.PackageVerificationCode{}, fmt.Errorf("got nil file for identifier %v", i)
66		}
67		if f.FileName != excludeFile {
68			// find the SHA1 hash, if present
69			for _, checksum := range f.Checksums {
70				if checksum.Algorithm == common.SHA1 {
71					shas = append(shas, checksum.Value)
72				}
73			}
74		}
75	}
76
77	// sort the strings
78	sort.Strings(shas)
79
80	// concatenate them into one string, with no trailing separators
81	shasConcat := strings.Join(shas, "")
82
83	// and get its SHA1 value
84	hsha1 := sha1.New()
85	hsha1.Write([]byte(shasConcat))
86	bs := hsha1.Sum(nil)
87
88	code := common.PackageVerificationCode{
89		Value:         fmt.Sprintf("%x", bs),
90		ExcludedFiles: []string{excludeFile},
91	}
92
93	return code, nil
94}
95
96// GetVerificationCode2_3 takes a slice of files and an optional filename
97// for an "excludes" file, and returns a Package Verification Code calculated
98// according to SPDX spec version 2.3, section 3.9.4.
99func GetVerificationCode2_3(files []*v2_3.File, excludeFile string) (common.PackageVerificationCode, error) {
100	// create slice of strings - unsorted SHA1s for all files
101	shas := []string{}
102	for i, f := range files {
103		if f == nil {
104			return common.PackageVerificationCode{}, fmt.Errorf("got nil file for identifier %v", i)
105		}
106		if f.FileName != excludeFile {
107			// find the SHA1 hash, if present
108			for _, checksum := range f.Checksums {
109				if checksum.Algorithm == common.SHA1 {
110					shas = append(shas, checksum.Value)
111				}
112			}
113		}
114	}
115
116	// sort the strings
117	sort.Strings(shas)
118
119	// concatenate them into one string, with no trailing separators
120	shasConcat := strings.Join(shas, "")
121
122	// and get its SHA1 value
123	hsha1 := sha1.New()
124	hsha1.Write([]byte(shasConcat))
125	bs := hsha1.Sum(nil)
126
127	code := common.PackageVerificationCode{
128		Value:         fmt.Sprintf("%x", bs),
129		ExcludedFiles: []string{excludeFile},
130	}
131
132	return code, nil
133}
134