Files
trivy/pkg/cache/key.go
2024-06-21 06:35:33 +00:00

84 lines
2.3 KiB
Go

package cache
import (
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"os"
"path/filepath"
"golang.org/x/mod/sumdb/dirhash"
"golang.org/x/xerrors"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/artifact"
)
func CalcKey(id string, analyzerVersions analyzer.Versions, hookVersions map[string]int, artifactOpt artifact.Option) (string, error) {
// Sort options for consistent results
artifactOpt.Sort()
artifactOpt.MisconfScannerOption.Sort()
h := sha256.New()
// Write ID, analyzer/handler versions, skipped files/dirs and file patterns
keyBase := struct {
ID string
AnalyzerVersions analyzer.Versions
HookVersions map[string]int
SkipFiles []string
SkipDirs []string
FilePatterns []string `json:",omitempty"`
}{id, analyzerVersions, hookVersions, artifactOpt.WalkerOption.SkipFiles, artifactOpt.WalkerOption.SkipDirs, artifactOpt.FilePatterns}
if err := json.NewEncoder(h).Encode(keyBase); err != nil {
return "", xerrors.Errorf("json encode error: %w", err)
}
// Write check, data contents and secret config file
paths := append(artifactOpt.MisconfScannerOption.PolicyPaths, artifactOpt.MisconfScannerOption.DataPaths...)
// Check if the secret config exists.
if _, err := os.Stat(artifactOpt.SecretScannerOption.ConfigPath); err == nil {
paths = append(paths, artifactOpt.SecretScannerOption.ConfigPath)
}
for _, p := range paths {
hash, err := hashContents(p)
if err != nil {
return "", err
}
if _, err := h.Write([]byte(hash)); err != nil {
return "", xerrors.Errorf("sha256 write error: %w", err)
}
}
return fmt.Sprintf("sha256:%x", h.Sum(nil)), nil
}
func hashContents(path string) (string, error) {
fi, err := os.Stat(path)
if err != nil {
return "", xerrors.Errorf("file %q stat error: %w", path, err)
}
var hash string
if fi.IsDir() {
hash, err = dirhash.HashDir(path, "", dirhash.DefaultHash)
if err != nil {
return "", xerrors.Errorf("hash dir error (%s): %w", path, err)
}
} else {
hash, err = dirhash.DefaultHash([]string{filepath.Base(path)}, func(_ string) (io.ReadCloser, error) {
return os.Open(path)
})
if err != nil {
return "", xerrors.Errorf("hash file error (%s): %w", path, err)
}
}
return hash, nil
}