diff --git a/internal/common/fips.go b/internal/common/fips.go new file mode 100644 index 0000000000..f62ef52d2c --- /dev/null +++ b/internal/common/fips.go @@ -0,0 +1,37 @@ +package common + +import ( + "bufio" + "os" + "strings" +) + +const ( + FIPSEnabledImageWarning = `The host building this image is not ` + + `running in FIPS mode. The image will still be FIPS compliant. ` + + `If you have custom steps that generate keys or perform ` + + `cryptographic operations, those must be considered non-compliant.` +) + +var ( + FIPSEnabledFilePath = "/proc/sys/crypto/fips_enabled" +) + +func IsBuildHostFIPSEnabled() (enabled bool) { + file, err := os.Open(FIPSEnabledFilePath) + if err != nil { + return + } + defer file.Close() + buf := []byte{} + _, err = file.Read(buf) + if err != nil { + return + } + scanner := bufio.NewScanner(file) + scanner.Scan() + if err := scanner.Err(); err != nil { + return + } + return strings.TrimSpace(scanner.Text()) == "1" +} diff --git a/internal/common/fips_test.go b/internal/common/fips_test.go new file mode 100644 index 0000000000..58d73d48ec --- /dev/null +++ b/internal/common/fips_test.go @@ -0,0 +1,38 @@ +package common + +import ( + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFIPSEnabledHost(t *testing.T) { + file, err := os.CreateTemp("/tmp", "fips_enabled") + assert.NoError(t, err, "unable to create tmp file") + defer file.Close() + defer os.Remove(file.Name()) + FIPSEnabledFilePath = file.Name() + + fileContents := []string{ + "", + "0\n", + "1\n", + "xxxxxx\n", + } + + for _, fileContent := range fileContents { + err = file.Truncate(0) + assert.NoError(t, err, "truncating file: %s", file.Name()) + _, err = file.Seek(0, 0) + assert.NoError(t, err, "seeking the begining of file: %s", file.Name()) + _, err = file.Write([]byte(fileContent)) + assert.NoError(t, err, "unable to write to file: %s", file.Name()) + if strings.TrimSpace(fileContent) == "1" { + assert.Equal(t, IsBuildHostFIPSEnabled(), true) + } else { + assert.Equal(t, IsBuildHostFIPSEnabled(), false) + } + } +} diff --git a/pkg/distro/fedora/imagetype.go b/pkg/distro/fedora/imagetype.go index 478004f046..7385d6a27c 100644 --- a/pkg/distro/fedora/imagetype.go +++ b/pkg/distro/fedora/imagetype.go @@ -392,5 +392,10 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp return nil, err } + if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() { + w := fmt.Sprintln(common.FIPSEnabledImageWarning) + return []string{w}, nil + } + return nil, nil } diff --git a/pkg/distro/rhel8/imagetype.go b/pkg/distro/rhel8/imagetype.go index 5343b9dff9..500dc5ecb8 100644 --- a/pkg/distro/rhel8/imagetype.go +++ b/pkg/distro/rhel8/imagetype.go @@ -427,5 +427,11 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp return warnings, err } + if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() { + w := fmt.Sprintln(common.FIPSEnabledImageWarning) + log.Print(w) + warnings = append(warnings, w) + } + return warnings, nil } diff --git a/pkg/distro/rhel9/imagetype.go b/pkg/distro/rhel9/imagetype.go index d4713ce17f..584fb0cade 100644 --- a/pkg/distro/rhel9/imagetype.go +++ b/pkg/distro/rhel9/imagetype.go @@ -442,5 +442,11 @@ func (t *imageType) checkOptions(bp *blueprint.Blueprint, options distro.ImageOp return warnings, err } + if customizations.GetFIPS() && !common.IsBuildHostFIPSEnabled() { + w := fmt.Sprintln(common.FIPSEnabledImageWarning) + log.Print(w) + warnings = append(warnings, w) + } + return warnings, nil }