diff --git a/attestation/file/file.go b/attestation/file/file.go index 2646dad9..c1a6ef45 100644 --- a/attestation/file/file.go +++ b/attestation/file/file.go @@ -54,7 +54,7 @@ func RecordArtifacts(basePath string, baseArtifacts map[string]cryptoutil.Digest return err } - artifacts[relPath + string(os.PathSeparator)] = dir + artifacts[relPath+string(os.PathSeparator)] = dir return filepath.SkipDir } diff --git a/attestation/file/file_test.go b/attestation/file/file_test.go index 73344bff..62f2ba73 100644 --- a/attestation/file/file_test.go +++ b/attestation/file/file_test.go @@ -20,6 +20,7 @@ import ( "path/filepath" "testing" + "github.com/gobwas/glob" "github.com/in-toto/go-witness/cryptoutil" "github.com/stretchr/testify/require" ) @@ -38,13 +39,15 @@ func TestBrokenSymlink(t *testing.T) { symTestDir := filepath.Join(dir, "symTestDir") require.NoError(t, os.Symlink(testDir, symTestDir)) - _, err := RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}) + dirHash := make([]glob.Glob, 0) + + _, err := RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}, dirHash) require.NoError(t, err) // remove the symlinks and make sure we don't get an error back require.NoError(t, os.RemoveAll(testDir)) require.NoError(t, os.RemoveAll(testFile)) - _, err = RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}) + _, err = RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}, dirHash) require.NoError(t, err) } @@ -57,7 +60,40 @@ func TestSymlinkCycle(t *testing.T) { symTestDir := filepath.Join(dir, "symTestDir") require.NoError(t, os.Symlink(dir, symTestDir)) + dirHash := make([]glob.Glob, 0) + // if a symlink cycle weren't properly handled this would be an infinite loop - _, err := RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}) + _, err := RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}, dirHash) + require.NoError(t, err) +} + +func TestDirHash(t *testing.T) { + dir := t.TempDir() + testFile := filepath.Join(dir, "testfile") + require.NoError(t, os.WriteFile(testFile, []byte("some dummy data"), os.ModePerm)) + testDir := filepath.Join(dir, "testdir") + require.NoError(t, os.Mkdir(testDir, os.ModePerm)) + testFile2 := filepath.Join(testDir, "testfile2") + require.NoError(t, os.WriteFile(testFile2, []byte("more dummy data"), os.ModePerm)) + + dirHashGlobs := make([]glob.Glob, 0) + + dirHash := "testdir" + dirHashGlobItem, _ := glob.Compile(dirHash) + dirHashGlobs = append(dirHashGlobs, dirHashGlobItem) + + artifacts, err := RecordArtifacts(dir, map[string]cryptoutil.DigestSet{}, []cryptoutil.DigestValue{{Hash: crypto.SHA256}}, map[string]struct{}{}, dirHashGlobs) require.NoError(t, err) + + // Below command is example usage on the above created scenario for testdir. + // find . -type f | cut -c3- | LC_ALL=C sort | xargs -r sha256sum | sha256sum + dirHashSha256 := "ba9842eac063209c5f67c5a202b2b3a710f8f845f1d064f54af56763645b895b" + + require.Len(t, artifacts, 2) + + dirDigestSet := artifacts["testdir/"] + dirDigestSetMap, err := dirDigestSet.ToNameMap() + require.NoError(t, err) + + require.Equal(t, dirDigestSetMap["sha256"], dirHashSha256) } diff --git a/cryptoutil/dirhash.go b/cryptoutil/dirhash.go index f35e8c62..b17efb71 100644 --- a/cryptoutil/dirhash.go +++ b/cryptoutil/dirhash.go @@ -44,4 +44,4 @@ func DirhHashSha256(files []string, open func(string) (io.ReadCloser, error)) (s fmt.Fprintf(h, "%x %s\n", hf.Sum(nil), file) } return hex.EncodeToString(h.Sum(nil)), nil -} \ No newline at end of file +}