blob: 53f0c9ab5822608278a14fbccab54fb58cacae17 [file] [log] [blame] [edit]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package fips140
import (
"crypto/sha256"
"flag"
"fmt"
"internal/testenv"
"maps"
"os"
"path/filepath"
"slices"
"strings"
"testing"
)
var update = flag.Bool("update", false, "update GOROOT/lib/fips140/fips140.sum")
func TestSums(t *testing.T) {
lib := filepath.Join(testenv.GOROOT(t), "lib/fips140")
file := filepath.Join(lib, "fips140.sum")
sums, err := os.ReadFile(file)
if err != nil {
t.Fatal(err)
}
lines := strings.SplitAfter(string(sums), "\n")
zips, err := filepath.Glob(filepath.Join(lib, "*.zip"))
if err != nil {
t.Fatal(err)
}
format := func(name string, sum [32]byte) string {
return fmt.Sprintf("%s %x\n", name, sum[:])
}
want := make(map[string]string)
for _, zip := range zips {
data, err := os.ReadFile(zip)
if err != nil {
t.Fatal(err)
}
name := filepath.Base(zip)
want[name] = format(name, sha256.Sum256(data))
}
// Process diff, deleting or correcting stale lines.
var diff []string
have := make(map[string]bool)
for i, line := range lines {
if line == "" {
continue
}
if strings.HasPrefix(line, "#") || line == "\n" {
// comment, preserve
diff = append(diff, " "+line)
continue
}
name, _, _ := strings.Cut(line, " ")
if want[name] == "" {
lines[i] = ""
diff = append(diff, "-"+line)
continue
}
have[name] = true
fixed := want[name]
delete(want, name)
if line == fixed {
diff = append(diff, " "+line)
} else {
// zip hashes should never change once listed
t.Errorf("policy violation: zip file hash is changing:\n-%s+%s", line, fixed)
lines[i] = fixed
diff = append(diff, "-"+line, "+"+fixed)
}
}
// Add missing lines.
// Sort keys to avoid non-determinism, but overall file is not sorted.
// It will end up time-ordered instead.
for _, name := range slices.Sorted(maps.Keys(want)) {
line := want[name]
lines = append(lines, line)
diff = append(diff, "+"+line)
}
// Show diffs or update file.
fixed := strings.Join(lines, "")
if fixed != string(sums) {
if *update && !t.Failed() {
t.Logf("updating GOROOT/lib/fips140/fips140.sum:\n%s", strings.Join(diff, ""))
if err := os.WriteFile(file, []byte(fixed), 0666); err != nil {
t.Fatal(err)
}
return
}
t.Errorf("GOROOT/lib/fips140/fips140.sum out of date. changes needed:\n%s", strings.Join(diff, ""))
}
}